VaNaTiC Geschrieben 16. Februar 2009 Geschrieben 16. Februar 2009 Hallo, habe anscheinend ein Verständnisproblem mit der Templates-Fehlermeldung. Habe das Problem auf ein kleines Sample reduziert. Gegeben sei der Typ und die Variable typedef map<int,string> SimpleMap; SimpleMap simple; simple[0] = "null"; simple[1] = "eins"; simple[2] = "zwei"; simple[3] = "drei"; simple[4] = "vier"; simple[5] = "fünf"; Für die Ausgabe eines Iterators als Test nutze ich: ostream& operator<< (ostream& out, const SimpleMap::value_type & p) { return out << "[" << p.first << "=>" << p.second << "]"; } cout << *simple.begin() << endl; // Beispielausgabe Wenn ich jetzt die gesamte Map ausgeben will wollte ich nutzen: ostream& operator<< (ostream& out, const SimpleMap & m) { // Variante 1 ostream_iterator< SimpleMap::value_type >output( out, "\n" ); copy( m.begin(), m.end(), output); return out; } Das liefert mir jedoch einen cryptischen STL-Fehler: Wenn ich statt einer Map, nur eine Vector<int> nutze, geht das prima. Ich hab mir jetzt mit folgendem Code geholfen: ostream& operator<< (ostream& out, const SimpleMap & m) { // Variante 2 for ( SimpleMap::const_iterator I = m.begin(), E = m.end(); I != E; ++I ) out << *I << endl; return out; } Aber das kanns doch nicht sein oder? Wo liegt denn der Unterschied zwischen den beiden Konstrukten? vector<int> liste; ostream_iterator< int >output( cout, "\n" ); copy(liste.begin(),liste.end(),output); map<int,string> MyMap; ostream_iterator< MyMap::value_type >output2( cout, "\n" ); copy(liste.begin(),liste.end(),output2); Oder wird bei copy(...) nicht der operator<< verwendet?
AndiE Geschrieben 16. Februar 2009 Geschrieben 16. Februar 2009 Hallo, bei VC 6++ findest du unter "?.Inhalt" bei "Willkommen.."/"Reference"/"C/C++ Language..."/"Standart ..."/"STL sample..." ein Beispiel zum Umgang mit map.(map::insert, ...) Danach wären bereits die Dateneinträge im ersten Codeabschnitt falsch. simple["NUll"]=0; Kannst du die Fehlermeldungen näher beschreiben? Wo sie wann eintreten? LG André
Klotzkopp Geschrieben 16. Februar 2009 Geschrieben 16. Februar 2009 Da hast du IMHO eine dunkle Ecke von C++ gefunden. Oder wird bei copy(...) nicht der operator<< verwendet?Doch. Aber in diesem Fall liegt der Aufruf des Operators im Namensraum std. Darum wird auch dort zuerst nach einem Operator gesucht. In std liegen natürlich jede Menge operator<<, also beschränkt sich die Überladungsauflösung auf den Namensraum std. Dein Operator ist aber im globalen Namensraum, und wird daher nicht gefunden.
VaNaTiC Geschrieben 17. Februar 2009 Autor Geschrieben 17. Februar 2009 @AndiE: Ich habe keine Ahnung wovon Du sprichst. Meine Map-Zuweisung ist sehr wohl korrekt @Klotzkopp: Danke, darauf wäre ich nie gekommen! Kann man das irgendwie umgehen, oder doch nur mit Variante 2? Wenn ich das richtig verstanden habe, ist also der operator<< den copy() benutzen will im namespace std. Könnte ich den nicht in meinem namensraum überschreiben?
Klotzkopp Geschrieben 17. Februar 2009 Geschrieben 17. Februar 2009 Kann man das irgendwie umgehen, oder doch nur mit Variante 2? Wenn ich das richtig verstanden habe, ist also der operator<< den copy() benutzen will im namespace std. Könnte ich den nicht in meinem namensraum überschreiben?Nein, da der Compiler zuerst im Namensraum std sucht, und dort natürlich jede Menge operator<< findet, werden andere Namensräume gar nicht durchsucht. Dann beginnt die Suche nach einer passenden Überladung, und da es in std keinen Operator für std::pair in irgendeiner Form gibt, schlägt das fehl. Andere Namensräume werden aber trotzdem nicht durchsucht. Praktisch könntest du deinen Operator in den Namensraum std stecken. Das wird häufig benutzt, um std::swap für eigene Typen zu überladen. Theoretisch gesehen erzeugt das allerdings undefiniertes Verhalten. Ich glaube aber, dass das nur daher rührt, dass es dann zu unerwarteten Namenskonflikten kommen, nicht dass das irgendein Problem für den Compiler darstellt.
VaNaTiC Geschrieben 17. Februar 2009 Autor Geschrieben 17. Februar 2009 @Klotzkopp: Klasse Sache, ich habe den pair-operator einfach nach std verschoben. Und siehe da funktioniert prima und wie gewünscht mit Variante 1. namespace std { ostream& operator<< (ostream& out, const SimpleMap::value_type & p) { return out << "[" << p.first << "=>" << p.second << "]"; } } @AndiE: Kein Problem, das passiert. Ich gebe auch zu, dass das Beispiel map<int,string> und dann map[0]=text" unglücklich gewählt ist. Die map<string,int> mit map["text] = 0 wäre auf den ersten Blick wohl die bessere Wahl.
Empfohlene Beiträge
Erstelle ein Benutzerkonto oder melde Dich an, um zu kommentieren
Du musst ein Benutzerkonto haben, um einen Kommentar verfassen zu können
Benutzerkonto erstellen
Neues Benutzerkonto für unsere Community erstellen. Es ist einfach!
Neues Benutzerkonto erstellenAnmelden
Du hast bereits ein Benutzerkonto? Melde Dich hier an.
Jetzt anmelden