Entscheidend ist jedoch, dass Code, der str_stream() benutzt, im Vergleich zu to_string effektiver ist, da ein String-Stream wesentlich besser für das Anhängen optimiert ist als ein String. Das kann man selbst überprüfen, indem man den Test in Listing G ausführt. Je nach der eigenen STL-Implementierung wird man sehen, dass str_stream() mindestens doppelt so schnell ausgeführt wird wie to_string(). Je komplizierter der String-Ausdruck ist, desto besser wird str_stream() im Vergleich abschneiden.
Debugging
Wie bereits erwähnt besteht einer der Vorzüge von to_string() in seinen Debugging-Fähigkeiten. Man kann aber auch str_stream() Debug-freundlicher machen: Im Debug-Modus hält man einfach neben dem Stream auch einen String bereit (Listing H).
Einen String anstelle eines Streams zu verwenden ist keine so gute Idee; die Kommentare in Listing I zeigen auf, warum das so ist.
Version 1.6: inklusive Formatierung
Um auch formatieren zu können, muss man IO-Manipulatoren in den str_stream() schreiben können. Es gibt zwei Arten von IO-Manipulatoren:
- Funktionen (std::oct, std::dec, std::scientific etc.)
- Objekte (std::setw, std::setfill etc.)
Die hier vorgestellte Implementierung erlaubt Objekte als IO-Manipulatoren, da alle Objekte in den Stream geschrieben werden dürfen. Man kann auch Funktionen zulassen (Listing J).
Version 1.9: Verwendung ähnlich wie to_string
Manchmal wird man dennoch to_string gegenüber str_string den Vorzug geben, z. B. wenn man nur einen Wert hinzufügen möchte:
Nun soll str_string so modifiziert werden, dass es wie to_string funktioniert. Dazu muss nur ein Constructor per Template hinzugefügt werden, der << für sein Argument aufruft. Zum Kompilieren musste der Code etwas umgestellt werden (Listing K).
Version 6.0: mit jedem Typ von char arbeiten können
Bislang funktioniert str_stream nur mit char-Streams. Eine allgemeine Lösung sollte jedoch für jede Art von Stream funktionieren. Auch wenn dadurch der Code komplizierter wird, lohnt sich der Aufwand. Die neue Version von str_stream ahmt vorhandenen STL-Code nach: Es gibt einen basic_str_stream mit zwei Parametern als Template: char_type und char_traits.
Es gibt zwei typedefs: str_stream und wstr_streams. Vorhandener Client-Code funktioniert auch weiterhin. In Listing L wird man bemerken, dass es vier Dateien gibt: str_stream.h, str_stream_vc_before.h, str_stream_vc_after.h und example.cpp. Die Dateien str_stream_vc_[before/after].h enthalten Workarounds für Visual C, während example.cpp ein Beispiel für die Verwendung von str_stream zeigt.
Mögliche Verbesserungen
Die Funktion str_stream sollte mit jedem Typ funktionieren, der über einen überladenen Operator << verfügt, doch der folgende Code gibt falsche Daten aus:
Das liegt daran, dass man versucht, einen wide string in einen narrow stream zu schreiben. Der wide string wird als Zeiger behandelt und daher werden die falschen Daten in s gespeichert. Dasselbe passiert allerdings mit jedem Stream:
Natürlich wünscht man sich eine automatische Konvertierung, wenn man in str_stream() schreibt, so wie hier:
Dies ist ein gültiger Request und gar nicht so schwierig zu implementieren. Eine effiziente Implementierung ist allerdings aus den folgenden Gründen nicht ganz so einfach:
- Beim Schreiben eines Werts muss man festlegen, ob es sich um einen String handelt.
- Falls der Wert kein String ist, kann er wie gehabt geschrieben werden.
- Falls er ein String ist, muss man feststellen, ob er unverändert geschrieben werden kann.
– Falls er unverändert geschrieben werden kann, wird er ohne das Erstellen temporärer Daten geschrieben.
– Andernfalls wird der Wert erst konvertiert und dann geschrieben.
Automatische Konvertierung ist zwar schwierig, aber die Mühe lohnt sich auf jeden Fall.
Neueste Kommentare
2 Kommentare zu Die perfekte Convert-to-string-Funktion in C++
Kommentar hinzufügenVielen Dank für Ihren Kommentar.
Ihr Kommentar wurde gespeichert und wartet auf Moderation.
Listing G
Beim Lesen fehlte mir "Listing G". Anscheinend ist kein Link vorhanden.
AW: Listing G
Vielen Dank für Ihren Hinweis. Das Listing ist jetzt korrekt verlinkt.