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.

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

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