VaNaTiC Geschrieben 16. Februar 2009 Teilen 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? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
AndiE Geschrieben 16. Februar 2009 Teilen 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é Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 16. Februar 2009 Teilen 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. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
VaNaTiC Geschrieben 17. Februar 2009 Autor Teilen 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? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
AndiE Geschrieben 17. Februar 2009 Teilen Geschrieben 17. Februar 2009 Ok. Fehler meinerseits. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 17. Februar 2009 Teilen 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. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
VaNaTiC Geschrieben 17. Februar 2009 Autor Teilen 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. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.