Pointer in std::map?
-
Hallo.
Gibt es eine simple Möglichkeit, einen Pointer als Key in std::map zu benutzen?
Beispiel:class Player { public: Player(const string &strName); const string &GetName() const; private: string m_strName; }; std::map<Player*, int> Data; // ... Player *pLocalPlayer = new Player("heinz"); // ... Data[pLocalPlayer] = 0; // ... std::map<Player*, int>::iterator it = Data.find(pLocalPlayer); // nichts wurde gefunden, it steht auf Data.end()Und das, obwhol die Adresse von pLocalPlayer sich nicht verändert hat. Das Objekt bleibt während der kompletten Laufzeit am selben Fleck.
Zum Debuggen habe ich mal die std::map ausgegeben (also durchiteriert), und mit erstaunen festgestellt, dass sich pLocalPlayer und it->first unterscheiden. Wie kann das angehen? Erstellt std::map heimlich eine neue Instanz?! Wie soll das gehen? Ich bin ratlos.
Edit: Wenn man als Außenstehender den Code anschaut, sieht es so aus, als ob ich einen großen Designfehler habe. Ich kann euch beruhigen: Nein, der liegt nicht vor. Es hat seinen Grund warum ich das so - und nicht anders - speichern muss.
Gruß
-
theliquidwave schrieb:
Player *pLocalPlayer = new Player("heinz"); // ... Data[pPlayer] = 0; // ... std::map<Player*, int>::iterator it = Data.find(pLocalPlayer); // nichts wurde gefunden, it steht auf Data.end()Du erzeugst ein pLocalPlayer, fügst ein pPlayer ein und suchst nach pLocalPlayer.
-
Naja. Das war nur ein Schreibfehler. Da sollte natürlich auch pLocalPlayer hin...
Danke für den Hinweis.Gruß
-
theliquidwave schrieb:
Edit: Wenn man als Außenstehender den Code anschaut, sieht es so aus, als ob ich einen großen Designfehler habe. Ich kann euch beruhigen: Nein, der liegt nicht vor. Es hat seinen Grund warum ich das so - und nicht anders - speichern muss.
Naja, wenn die Player-Objekte nicht in einem Array liegen, dann liegt wirklich ein Designfehler vor, weil du undefiniertes Verhalten erzeugst. Man darf nicht einfach so Zeiger miteinander vergleichen. Ein Zeigervergleich ist nur erlaubt bei Zeigern, welche auf Elemente aus einem gemeinsamen Array verweisen.
Wenn die Objekte in einem Array sind, dann hast du was falsch gemacht.
std::maperzeugt sicher nicht eine eigene Kopie des Objektes. Der Zeiger müsste den gleichen Wert haben. Kannst du mal ein kleines Programm machen, welches den Fehler reproduziert?Grüssli
-
Dravere schrieb:
Ein Zeigervergleich ist nur erlaubt bei Zeigern, welche auf Elemente aus einem gemeinsamen Array verweisen.
Für einen Vergleich über die relationalen Operatoren ist das Verhalten unspecified (d.h. implementierungsabhängig und nicht zwangsläufig dokumentiert):
§5.9 Relational operators schrieb:
If two pointers p and q of the same type point to different objects that are not members of the same object or elements of the same array or to different functions, or if only one of them is null, the results of p<q, p>q, p<=q, and p>=q are unspecified.
Allerdings garantiert
std::less, welches vonstd::mapohne weitere Angabe verwendet wird, eine totale Ordnung:§20.3.3/8 Comparisons schrieb:
For templates greater, less, greater_equal, and less_equal, the specializations for any pointer type yield a total order, even if the built-in operators <, >, <=, >= do not.
-
Ok, ich rudere zurück... Wieso bin ich so blind?!
CPlayer *pPlayer = new CPlayer(pIdentity); this->m_Players.push_back(new CPlayer(pIdentity));Das ist der exakte Code (etwas andere Umstände, deshalb gerade mit einer Liste.
Das erklärt alles -.-Tut mir leid für dieses Missgeschick

Gruß

-
Also folgendes Programm gibt bei mir, wie erwartet
"heinz: 42"aus.#include <iostream> #include <string> #include <map> #include <cstdlib> using namespace std; class Player { public: Player(const string &strName) : m_strName(strName) { } const string &GetName() const { return m_strName; } private: string m_strName; }; int main(int argc, char* argv[]) { std::map<Player*, int> Data; Player *pLocalPlayer = new Player("heinz"); Data[pLocalPlayer] = 42; std::map<Player*, int>::iterator it = Data.find(pLocalPlayer); if (it == Data.end() ) { cout<<"Fehler"<<endl; } else { cout<< it->first->GetName() <<": "<< it->second<<endl; } return EXIT_SUCCESS; }Edit: Okay... etwas spät...
-
Jop,
trotzdem danke für die Mühe
Gruß