Seite 1 von 1

Const Correctness und operator[]

Verfasst: Fr Apr 26, 2013 10:52 am
von Glocke
Hi, folgendes Beispiel:

Code: Alles auswählen

#include <iostream>

class Test {
    public:
        std::string& operator[](std::string const & key) {
            // irgendwas
            std::string* s = new std::string(key);
            return *s;
        }
};

int main() {
    Test const t;
    std::string value = t["Hallo Welt"];
    std::cout << value << std::endl;
}
Leider kann ich mit der Compiler-Meldung
Fehler: Die Übergabe von »const Test« als »this«-Argument von »std::string& Test::operator[](const string&)« streicht Qualifizierer [-fpermissive]
nicht umgehen. Btw zeigt sie genau auf die Zeile

Code: Alles auswählen

std::string value = t["Hallo Welt"];
Kann mir jemand sagen was ich falsch mache? t soll zwingend Test const sein.

LG Glocke

/EDIT: Muss ich dann neben

Code: Alles auswählen

T_return& X::operator[](T_index const& index);
auch noch

Code: Alles auswählen

const T_return& X::operator[](T_index const& index) const;
implementieren, da mein Container (also mein t) konstant ist?

Re: Const Correctness und operator[]

Verfasst: Fr Apr 26, 2013 11:06 am
von Xin
Glocke hat geschrieben:Hi, folgendes Beispiel:

Code: Alles auswählen

#include <iostream>

class Test {
    public:
        std::string& operator[](std::string const & key) {
            // irgendwas
            std::string* s = new std::string(key);
            return *s;
        }
};
Seeekunde... wenn Du ein neues Objekt anlegst, dann kostet das - egal ob Du es auf dem Stack oder im Freispeicher anlegst.
Ein Objekt, das Du mit new anlegst, musst Du auch wieder entsorgen! Also bleib mal beim Stack.

Code: Alles auswählen

#include <iostream>

class Test {
    public:
        std::string& operator[](std::string const & key) {
            // irgendwas
            return std::string( value );
        }
};
Glocke hat geschrieben: Leider kann ich mit der Compiler-Meldung
Fehler: Die Übergabe von »const Test« als »this«-Argument von »std::string& Test::operator[](const string&)« streicht Qualifizierer [-fpermissive]
nicht umgehen. Btw zeigt sie genau auf die Zeile

Code: Alles auswählen

std::string value = t["Hallo Welt"];
Kann mir jemand sagen was ich falsch mache? t soll zwingend Test const sein.

/EDIT: Muss ich dann neben

Code: Alles auswählen

T_return& X::operator[](T_index const& index);
auch noch

Code: Alles auswählen

const T_return& X::operator[](T_index const& index) const;
implementieren, da mein Container (also mein t) konstant ist?
Du kannst auch ausschließlich nur die Const-Variante implementieren. Dann darfst Du aber halt keine (nicht-const) Referenzen in das Objekt zurückgeben. Da Du in dem Fall hier aber sowieso eine Kopie anlegst, passt das.

Re: Const Correctness und operator[]

Verfasst: Fr Apr 26, 2013 11:17 am
von Glocke
Xin hat geschrieben:Seeekunde... wenn Du ein neues Objekt anlegst, dann kostet das - egal ob Du es auf dem Stack oder im Freispeicher anlegst.
Ein Objekt, das Du mit new anlegst, musst Du auch wieder entsorgen! Also bleib mal beim Stack.

Code: Alles auswählen

#include <iostream>

class Test {
    public:
        std::string& operator[](std::string const & key) {
            // irgendwas
            return std::string( value );
        }
};
Das wollte ich eigentlich auch machen, nur mecker er da:

Code: Alles auswählen

Fehler: ungültige Initialisierung einer nicht-konstanten Referenz des Typs »std::string& {aka std::basic_string<char>&}« von R-Wert des Typs »std::string {aka std::basic_string<char>}«
Xin hat geschrieben:Du kannst auch ausschließlich nur die Const-Variante implementieren. Dann darfst Du aber halt keine (nicht-const) Referenzen in das Objekt zurückgeben. Da Du in dem Fall hier aber sowieso eine Kopie anlegst, passt das.
Okay, danke :D Bleibt nur noch das Problem von oben :D

Re: Const Correctness und operator[]

Verfasst: Fr Apr 26, 2013 12:02 pm
von Xin
Glocke hat geschrieben:Okay, danke :D Bleibt nur noch das Problem von oben :D
:oops: Das & muss dann natürlich auch weg, weil Du ja die neue Instanz rüberreichst:

Code: Alles auswählen

        std::string /* & */ operator[](std::string const & key) {