STL Map: Direkter Zugriff per Iterator?



  • Hi,

    folgendes Szenario:

    class ttest {
    public: int value;
    		void setValue(int val) {
    			value = val;
    		}
    };
    
    int main()
    {
    	map<string, ttest> testmap;
    	map<string, ttest>::const_iterator iter;
    
    	ttest x;
    	x.setValue(1);
    	testmap["a"] = x;
    
    	for(iter=testmap.begin(); iter!=testmap.end(); iter++) {
    		((ttest)iter->second).setValue(23);
    	}
    }
    

    Warum ist nach Abbarbeitung der Iteratorschleife testmap["a"].value immer noch 1? Habe ich über den Iterator nur lesenden Zugriff auf die Objekte in der Map? Oder bekomme ich per ((ttest)iter->second) nur eine lokale Kopie des Objektes?
    Wie kann ich denn direkt das Objekt an der Stelle iter->second manipulieren?

    Gruß, Thomas



  • Ah, böser Fehler.
    So gehts besser:

    (iter->second).setValue(23);
    

    Ist schon bösartig, dass sich der Iterator klaglos auf eine beliebige Klasse casten lässt.

    Trotzdem noch ne Frage, warum geht das nicht:

    ((ttest)(iter->second)).setValue(23);
    

    bzw. warum wird der Wert nicht gesetzt?

    Gruß, Thomas.



  • Weil du einen const_iterator verwendest.

    Der cast ist unnötig.



  • Der Wert wird korrekt gesetzt.
    Du musst jedoch beachten, das Deine Map eine Kopie von x hält.

    Ansonsten: Mit (<klasse>) sagst Du dem Compiler, das er einfach annehmen soll, das es Typ <klasse> ist. Du sagst also: Ich weiß was ich mache, tu es einfach!

    Bösartig ist der C Style Cast (oder der , der diesen einsetzt).

    Details siehe reinterpret_cast<T>();

    Was Du vermutlich suchst wäre ein static_cast<T>():

    static_cast<ttest>(iter->second).setValue(23);
    


  • Thomas++ schrieb:

    Ist schon bösartig, dass sich der Iterator klaglos auf eine beliebige Klasse casten lässt.

    Wäre bösartig, wenn das ginge, ja. Ist hier aber nicht so, du castest den Gesamtausdruck iter->second. Der hat eigentlich den Typ ttest&, und das wär auch gut so. Wenn du das nach ttest castest, machst du eigentlich dasselbe wie

    ttest(iter->second);
    

    du erzeugst also eine temporäre Kopie des Objektes, auf das iter->second verweist. Diese Kopie veränderst du durch setValue, das Original bleibt unbehelligt.

    Ich würd jetzt gern noch wissen, wie du überhaupt darauf kommst, hier casten zu müssen.



  • Wäre bösartig, wenn das ginge, ja. Ist hier aber nicht so, du castest den Gesamtausdruck iter->second.

    Ich dachte, ein Cast ist immer stärker bindend, also dass (typ)iter->second daselbe ist wie ((typ)iter)->second. Ist wohl doch nicht so?

    Ich würd jetzt gern noch wissen, wie du überhaupt darauf kommst, hier casten zu müssen.

    Bin ich von Java so gewöhnt, da ist mein Iterator meist vom Typ Object.

    Ein C-Cast ist kein C++-Cast, wieder was gelernt. 💡

    Gruß, Thomas



  • Thomas++ schrieb:

    ...((typ)iter)->second. ...

    😮 DAS wäre ja noch schlimmer !
    Damit würdest Du also einen map::const_iterator auf ttest casten (und ttest hat bestimmt weder Pointertyp (wg. "->") und wohl auch kein second())....

    Basher hat erklärt, dass Du hier gar nicht "wirklich" castest, sondern einfach ein neues (temporäres) Objekt anlegst...

    Gruß,

    Simon2.



  • Thomas++ schrieb:

    Ich dachte, ein Cast ist immer stärker bindend, also dass (typ)iter->second daselbe ist wie ((typ)iter)->second. Ist wohl doch nicht so?
    [...]
    Bin ich von Java so gewöhnt, da ist mein Iterator meist vom Typ Object.

    Tja was soll man da sagen außer: Lern C++ 🙂



  • Ja genau, das Problem ist dass ein "&" zwischen "ttest" und ")" fehlt.
    (Abgesehen von den ganzen anderen Problemen mit dem Code)


Anmelden zum Antworten