Zum Inhalt springen

C++STL: Problem map<x,y> Ausgabe mittels ostream_iterator


Empfohlene Beiträge

Geschrieben

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?

Geschrieben

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é

Geschrieben

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.

Geschrieben

@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?

Geschrieben
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.

Geschrieben

@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.

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 erstellen

Anmelden

Du hast bereits ein Benutzerkonto? Melde Dich hier an.

Jetzt anmelden

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...