Zuweisung an den Index-Operator?
-
Hallo,
ich habe hier eine Klasse die den Zugriff auf eine mehrdimensionale
Map hinter einem Index-Operator verbirgt. Ungefähr so:class A { privat: static map< string, map<string,string> > data; string section; public: A( string str ); // str wird nach pruefung section zugewiesen ~A() {}; string operator[](string name) {return data[section][name];}; }
Jetzt will ich eine Methode schreiben die bei der Zuweisung an den
Index-Operator angesprochen wird. Etwa so:A default("mySettings"); default["logfile"]="/var/log/myprog.log";
Ich will hier nicht direkt an date[][] zuweisen, sonst könnte ich ja eine Referenz zurückgeben, sondern nur wenn data["mySettings"]["logfile"].empty().
Was mir fehlt ist die richtige deklaration des operator[]= oder wie
auch immer der dann aussehen muss.Danke!
Peanut
[ Dieser Beitrag wurde am 10.04.2003 um 21:32 Uhr von Peanut editiert. ]
-
Original erstellt von Peanut:
**Ich will hier nicht direkt an date[][] zuweisen, sonst könnte ich ja eine Referenz zurückgeben, sondern nur wenn data["mySettings"]["logfile"].empty().
Was mir fehlt ist die richtige deklaration des operator[]= oder wie
auch immer der dann aussehen muss.
**kapiere ich nicht
-
dann liefer eine referenz auf den string zurück...
string& operator[](string &name) {return data[section][name];}
auch name solltest du per referenz übergeben da sonst eine überflüssige kopie erstellt wird...
-
Original erstellt von japro:
auch name solltest du per referenz übergeben da sonst eine überflüssige kopie erstellt wird...aber als const referenz!
-
Das mit der const-Referenz ist klar, ist nur bei der Vereinfachung für das Beispiel draufgegangen!
Was ich suche:
string& A::operator[]= (string const& index, string const& zuweisung) { // diesen operator gibt es eben nicht! if ( name[section][index].empty() ){ name[section][index]=zuweisung; return zuweisung; } else { return name[section][index]; } }
Bei der Frage wurde ich vom Mod des de.comp.lang.iso-c++ auf http://www.voyager.prima.de/cpp/proxy.html aufmerksam gemacht. Obwohl ich das Beispiel inzwischen am laufen habe ( vector::... muss durch vector<T, Assoc> ersetzt werden ) kann ich das gezeigte nicht auf mein Problem anwenden
Weitere Anfragen wurden mit in d.c.l.iso-c++ wurden mit
"Halte Dich nicht mit Syntaxspielereien auf. Wenn es
einfacher ist, zwei Methoden »read« und »write« zu schreiben, dann
tue das, statt ewig nach einem Gimmick zu suchen, der »=« verwendet."
abgetan.Aber ich bin der Meinung ich mache mir lieber einmal die Gedanken und ärgere mich nicht später immer wenn ich die Klasse benutze weil sie unhandlich ist. Ausserdem ist da ja auch die Sache mit dem Lerneffekt!
Danke
Mario
[ Dieser Beitrag wurde am 10.04.2003 um 21:30 Uhr von Peanut editiert. ]
-
Hallo,
also ich habe dein Vorhaben auch nicht verstanden. Kannst du das vielleicht mal an ein paar Beispielen erklären?
-
Ich nehm mal an, du willst folgendes:
A a; a["Blub"] = "Bla";
a["Blub"] = "Bla";
hier werden aber zwei operatoren aufgerufen:
a.operator [] ("Blub").operator = ("Bla");
das heißt du musst für a den operator [] überladen und für den Rückgabewert von A::operator [] den operator = überladen.[ Dieser Beitrag wurde am 10.04.2003 um 18:40 Uhr von Noesis editiert. ]
-
@HumeSikkins: Nimm die Klassen definition aus den ersten posting mit der Elementfunktion aus dem zweiten und du hast ein Beispiel!
@Noesis: Ahh, wenigstens einer versteht mich!
OK, Rückgabewert von A::operator [] gibt einen String zurück. String liegt nicht in meiner Gewalt also neue Klasse definieren:
class dummyString : public std::string{ string operator=(const string& str) {cout << "put code here" << endl; string::operator=(str); } }
und dann den return-Wert von A::operator[] auf dummyString gesetzt. Dann fingen die Probleme aber erst an, der Compiler meinte einen dummyString niht in einen String umwandeln zu können aber dummyStrings sind ja eigentlich Strings. Ich als Beginner habe dann gedacht, ich sei völlig auf dem Holzweg und habe um Hilfe geschrieen. Aber wenn der Ansatz stimmt werde ich mich nochmal in die Richtung orientieren und komme dann mit entsprechenden Problemen bei der Umsetzung nochmal auf euch zurück.
Bis hierher schon mal Danke!
Peanut
-
probiers mal mit
operator string & ()
oder
operator const string & () const
-
Ok, einen kleinen Teil habe ich glaube ich! Nur das eigentliche zuweisen will nicht!
class dummyString : public std::string { public: string& operator=(string const& str) { cout << "put your code here!" << endl; return std::string::operator=(str); } dummyString ( string const& str ) : std::string::basic_string(str){} }; class A { privat: static map< string, map<string,string> > data; string section; public: A( string str ); // str wird nach pruefung section zugewiesen ~A() {}; dummyString operator[](string name) {return data[section][name];}; } int main(void) { A a("name"); cout << "notconft:" << a["notconft"] >> endl; a["notconft"]="Hello World!"; cout << "notconft:" << a["notconft"] >> endl; }
Dabei kommt aber:
notconft:
put your code here!
notconft:und nicht
notconft:
put your code here!
notconft: Hello World!raus
Hinweise? Meine vermutung ist das
A::operator[]
eine Referenz zurückgeben muss damit
dummyString::operator=
dieser dann einen Wert zuweisen kann. Aber wenn ich den return-Wert von
A::operator[]
auf dummyString& ändere bekomme ich
initializing non-const `dummyString &' with `basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> >' will use a temporary
PS: Bitte noch keine Call-by...Hinweise, ich arbeite dran!
-
du erzeugst ja ein temporäres dummyString objekt aus einem std::string. und dann willst du eine referenz darauf zurückgeben, das geht nicht.
Wenn du das Schlüsselwort "explicit" vor dummyStrings Konstruktor dazutust, wirst du den Fehler vielleicht erst erkennen.
du änderst mal deine map inmap< string, map<string,dummyString> > data;
und den operator [] lässt du jetzt eine Referenz zurückgeben
Allerdings frage ich mich, wieso du nicht einfach eine Referenz auf einen std::string zurückgibst. Irgendwelche speziellen Prüfungen im dummyString::operator= notwendig?
edit: Smileys weg
[ Dieser Beitrag wurde am 11.04.2003 um 13:56 Uhr von davie editiert. ]
-
So, jetzt tut es! Hässlich ist nur, dass der dummyString eine globale-Klasse geworden ist. Kann man den in die A-Klasse (nicht die von Mercedes!) integrieren?
Naja, so läuft es ja erstmal!
Nochmal besten Dank an davie der doch auch Noesis war
!
#include <iostream> #include <string> #include <map> class dummyString : public std::string { public: string& operator=(string const& str) { cout << "put your code here!" << endl; return std::string::operator=(str); } dummyString ( string const& str ) : std::string::basic_string(str){} dummyString ( ) : std::string::basic_string(){} }; class A { private: static map< string, map<string,dummyString> > data; string section; public: A( string str ) : section(str){}; ~A() {}; dummyString& operator[](string name) {return data[section][name];}; }; map< string, map<string,dummyString> > A::data; int main(void) { A a("name"); cout << "notconft:" << a["notconft"] << endl; a["notconft"]="Hello World!"; cout << "notconft:" << a["notconft"] << endl; }
-
Letzte Fassung!
Jetzt ist es so wie ich mir das vorgestellt habe!#include <iostream> #include <string> #include <map> class A { public: class dummyString : public std::string { public: string& operator=(string const& str) { cout << "put your code here!" << endl; return std::string::operator=(str); } dummyString ( string const& str ) : std::string::basic_string(str){} dummyString ( ) : std::string::basic_string(){} }; private: static map< string, map<string,A::dummyString> > data; string section; public: A( string str ) : section(str){}; ~A() {}; A::dummyString& operator[](string name) {return data[section][name];}; }; map< string, map<string,A::dummyString> > A::data; int main(void) { A a("name"); cout << "notconft:" << a["notconft"] << endl; a["notconft"]="Hello World!"; cout << "notconft:" << a["notconft"] << endl; }