Angenommen, ich habe eine Funktion, die einen ostream &
Parameter o
nimmt und in diesen Ostream schreibt. Eine operator <<
Implementierung wäre ein gutes Beispiel.Soll ich einen temporären Ostream mit dem streambuf eines anderen Benutzers erstellen?
ostream& operator << (ostream& o, const MyThing& t)
{
// ... interesting code here ...
return o;
}
Innerhalb der Funktion möchte ich möglicherweise Formatierungsoptionen für den Stream angeben. Beispielsweise möchte ich, dass eine Zahl als Hex gedruckt wird, egal wie die o
konfiguriert ist, wenn sie an die Funktion übergeben wird.
Zweitens möchte ich in der Lage sein, Annahmen über die aktuellen Formatierungsflags zu machen. Zum Beispiel wäre es schön, davon ausgehen zu können, dass Zahlen als Dezimalzahlen formatiert sind, wenn ich nichts anderes wünsche.
Schließlich, bis die Funktion beendet Ich möchte die Formatierungsoptionen auf o
die gleichen wie sie vor dem Aufruf der Funktion waren, so dass sie für den Aufrufer unverändert angezeigt werden. Das ist einfach eine Frage der Höflichkeit gegenüber dem Anrufer.
Bisher habe ich dies erreicht, indem eine lokale ostringstream
innerhalb der Funktion zu schaffen, tun alle meine Arbeit an, dass (einschließlich Formatierungsoptionen einstellen) und die .str()
-o
am Ende der Funktion sendet. Die StackOverflow-Frage here legt nahe, dass Menschen, die klüger sind als ich, denselben Ansatz verfolgen. Es stört mich jedoch, dass ich so viele Daten in ostringstreams aufbewahre, die vielleicht früher an den Ausgang gesendet werden könnten (die Strings können ziemlich groß werden).
Ich habe zwei Fragen:
1) Ist es legal, idiomatisch, gute Form, usw. einen temporären (Stack basierte) Ostream um o.rdbuf()
zu erstellen und an diesem Ostream meine Arbeit tun? Meine eigenen Tests und die Seite unter cppreference.com scheint darauf hinzudeuten, dass ich es kann.
ostream& operator << (ostream& o_, const MyThing& t)
{
ostream o (o_.rdbuf());
// write stuff to "o",
// setting formatting options as I go.
return o_; // Formatting on the parameter ostream o_ unchanged.
}
2) Gibt es einen anderen, besseren Weg, den ich nicht berücksichtigt habe?
Diese Anrufe am besten in den Konstruktor und Destruktor platziert werden würde irgendein stapelbasiertes Objekt. Ich gehe davon aus, dass die Boost-Klassen das tun. – peterpi