string::operator[]



  • Tagchen,
    ich habe eine kleine String-Klasse mit std::string als Basis geschrieben, um eine bisherige, auf einem char-array basierende zu ersetzen.

    Mein Problem ist aktuell, dass Geschichten wie

    if(stringinstanz[0])
    

    mit Fehler abbrechen.

    Die Struktur meiner Klasse ist diese:

    class pstring : public string
    {
    	public:
    		pstring();
    		pstring( const char *str );
    		pstring( const string &str );
    		~pstring();
    
    		int caseCmp( const pstring &str, unsigned int len=pstring::npos );
    		int strcmp( const pstring &str, unsigned int len=pstring::npos );
    
    		pstring token( unsigned int pos, bool rest=false, const pstring &sep=" " ) const;
    		unsigned int split( const pstring &delim, vector<pstring> &ret, bool allowEmpty ) const;
    
    		operator bool() const;
    		operator const char*() const;
    };
    

    So, mein Problem ist nun, dass der standard operator[] nicht funktioniert:

    pstring name("+lx");
    if(name[0] == '+' || name[0] == '-') {}
    
    class-client.cpp: In member function »void client::checkMyHost(const char*, bool)«:
    class-client.cpp:32: Fehler: ISO C++ besagt, dass diese mehrdeutig sind, auch wenn die schlechteste Umwandlung für das erste besser ist als die schlechteste Umwandlung für das zweite:
    /usr/include/c++/4.3/bits/basic_string.h:718: Anmerkung: Kandidat 1: typename _Alloc::rebind<_CharT>::other::reference std::basic_string<_CharT, _Traits, _Alloc>::operator[](typename _Alloc::rebind<_CharT>::other::size_type) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]
    class-client.cpp:32: Anmerkung: Kandidat 2: operator[](const char*, int) <eingebaut>
    

    Selber den Operator ueberladen funktioniert selbstverfreilich auch nicht.
    Was kann man hier machen?
    C167



  • Standardmäßig wird kein operator[] erzeugt. Das mußt du schon selber machen wenn du ihn haben willst. Wo ist hier das Problem?



  • Das Problem ist folgendes:
    Bei Verwendung von

    const char operator[]( size_t pos ) const
    {
    	return at( pos );
    }
    

    fuehrt zu:

    class-client.cpp: In member function »void client::checkMyHost(const char*, bool)«:
    class-client.cpp:32: Fehler: ISO C++ besagt, dass diese mehrdeutig sind, auch wenn die schlechteste Umwandlung für das erste besser ist als die schlechteste Umwandlung für das zweite:
    pstring.h:52: Anmerkung: Kandidat 1: const char pstring::operator[](size_t) const
    class-client.cpp:32: Anmerkung: Kandidat 2: operator[](const char*, int) <eingebaut>
    

    Hab ich etwa falsch Ueberladen?



  • Stopp, ich hatte übersehen, dass du von string ableitest. Dann hast du natürlich deinen operator[] schon. Ableiten ist hier eigentlich nicht üblich, da der destruktor von string nicht virtual ist.
    Was dieser operator[](const char*, int) sein soll weiß ich jetzt auch nicht.



  • Vermutung: Kann es sein, dass

    operator const char*() const;
    

    dazu führt, dass der Compiler nicht mehr weiß, ob er jetzt in char* umwandeln soll und darauf den Operator [] anwenden soll, oder ob er den Operator direkt auf die Klasse anwenden soll. Probiere mal aus, ob es klappt, wenn du den impliziten Cast weg lässt.



  • Nur um sicher zu gehen: Operatoren werden alle uebernommen (public,protected,private natuerlich respektiert)? Mir wird naemlich alle Nase lang was anderes gesagt 😉

    Vllt helfen ein paar Infos ueber mein System:
    Debian GNU/Linux SID
    g++ (Debian 4.3.2-1) 4.3.2



  • ProgChild schrieb:

    Vermutung: Kann es sein, dass

    operator const char*() const;
    

    dazu führt, dass der Compiler nicht mehr weiß, ob er jetzt in char* umwandeln soll und darauf den Operator [] anwenden soll, oder ob er den Operator direkt auf die Klasse anwenden soll. Probiere mal aus, ob es klappt, wenn du den impliziten Case weg lässt.

    Aehm ja. Problem ist hierbei, dass es eben sehr viele casts gibt, die man nun durch ".c_str()" ersetzen muss, darum hab ich diesen cast ja ueberladen 😉
    Wenn ich durch die zig Zeilen Fehlermeldungen richtig durchsteige, moniert er nur noch die nun fehlende Umwandlung in "const char *". Aber schon interessant, wieder was gelernt.
    Vielen Dank soweit 🙂

    Ich werd mich mal dran machen, dieses ersetzen vorzunehmen, Kaffee ist vorhanden 🙂

    Bevor ichs vergesse: Die Standard-Implementierung sieht ja so aus:

    const char& operator[] ( size_t pos ) const;
          char& operator[] ( size_t pos );
    

    Was hat das zusaetzliche const am Ende der ersten Zeile zu suchen?



  • Die eine Funktion ist für konstante Instanzen deiner Klasse die andere für nicht konstante.



  • C167 schrieb:

    Bevor ichs vergesse: Die Standard-Implementierung sieht ja so aus:

    const char& operator[] ( size_t pos ) const;
          char& operator[] ( size_t pos );
    

    Was hat das zusaetzliche const am Ende der ersten Zeile zu suchen?

    Das ist die Version, die aufgerufen wird, wenn der String selbst `const` ist, also in folgendem Fall:

    string const hi = "Hello, world!";
    cout << hi[0];
    

    Hier ist also quasi der `this`-Zeiger ein Zeiger auf ein konstantes Objekt.



  • vielen Dank euch allen 🙂

    Schlussendlich wird hier wohl (mal wieder) ein Patch von ueber 2000 Zeilen rauskommen, die Entwickler, denen ich den Patch senden werde, werden sich freuen 😉


Anmelden zum Antworten