Verwendung von stringstream innerhalb der ostream-Funktion

8

Ich suche nach ostream Operatoren für einige Mathematikklassen (Matrix, Vektor, etc.). Ein Freund hat festgestellt, dass die gcc Standardbibliotheksimplementierung des ostream Operators für std::complex die interne Verwendung von enthält ein String-Stream, um die Ausgabe zu formatieren, bevor sie an das tatsächliche ostream übergeben wird:

%Vor%

Dieses Muster ist auch im Boost sichtbar. Wir versuchen herauszufinden, ob dies ein Muster ist, dem man folgen sollte. Es gab Bedenken, dass ein zusätzlicher Header für den String-Stream eingeschlossen werden muss und dass zusätzliche Heap-Zuweisungen im String-Stream erforderlich sind, die möglicherweise vermieden werden könnten.

Am vernünftigsten wurde vorgeschlagen, dass, wenn der Client diese Funktionalität benötigt, sie den String-Stream erstellen und die Pre-Pass-Funktion selbst übernehmen können.

Kann jemand mir helfen zu verstehen, warum dies als gute Praxis angesehen wird und ob ich es übernehmen sollte?

    
MichaelJones 15.10.2012, 21:16
quelle

3 Antworten

6

Überlegen Sie, was passiert, wenn Sie eine Ausgabebreite für den Ostream festlegen und dann einen std :: complex schreiben - Sie möchten nicht, dass sich die Breite nur auf den ersten Ausgabevorgang auswirkt (zB '(' -Zeichen)

%Vor%

Dies sollte "(0,1)     " nicht "(         0,1)"

ausgeben

Wenn Sie die gesamte Ausgabe als einzelne Zeichenfolge formatieren und dann ausschreiben, berücksichtigt die Ausgabe die Feldbreite und andere im Stream festgelegte Formatierungsflags.

    
Jonathan Wakely 15.10.2012, 21:23
quelle
4

Der in einer anderen Antwort angegebene Threading-Grund wird nicht wirklich funktionieren: Die Zeichenfolge kann immer noch auf der Stream-Buffer-Ebene aufgeteilt werden, da diese Operationen nicht atomar sind, wenn sie von mehreren Threads aufgerufen werden.

Allerdings gibt es zwei Überlegungen, die relevant sind:

  1. Bei bestimmten Ausgaben möchten Sie die Format-Flag-Einstellungen vorübergehend ändern. Sie möchten beispielsweise sicherstellen, dass eine bestimmte Zeichenfolge in Hexadezimalschreibweise angezeigt wird, für andere Dezimalschreibweise und Sie möchten den Stream in seinen ursprünglichen Zustand zurückversetzen.
  2. Noch wichtiger ist, dass die Bedeutung des width() einer Ausgabe die Anzahl der Zeichen ist, die die gesamte Formatierungszeichenfolge mindestens belegen sollte. Wenn Sie Ausgabeoperatoren intern für einen anderen Ausgabeoperator verwenden, würden Sie das erste Element so einrichten, dass es die Breite einnimmt, und nicht die gesamte resultierende Zeichenfolge, die aus mehreren Komponenten besteht. Bei einer komplexen Zahl würde das reelle Element beispielsweise width() und nicht die Kombination aus realem Element, Komma und imaginärem Element belegen.
Dietmar Kühl 15.10.2012 21:26
quelle
2

Ein Hauptzweck dieses Patterns besteht darin, zu vermeiden, dass die Manipulatoren / Flags des ursprünglichen Streams beibehalten und vor dem Zurücksetzen zurückgesetzt werden. Boost.IoStateSavers beseitigt die Notwendigkeit dafür, also würde ich sagen, dass die Verwendung dieser Bibliothek eine sein würde bessere Praxis.

    
ildjarn 15.10.2012 21:22
quelle

Tags und Links