Veröffentlicht 16. Februar 200916 j 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?
16. Februar 200916 j 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é
16. Februar 200916 j 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.
17. Februar 200916 j Autor @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?
17. Februar 200916 j 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.
17. Februar 200916 j Autor @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.
Archiv
Dieses Thema wurde archiviert und kann nicht mehr beantwortet werden.