Suppose I have a function that takes an ostream &
parameter o
and writes to that ostream. An operator <<
implementation would be a good example.
ostream& operator << (ostream& o, const MyThing& t)
{
// ... interesting code here ...
return o;
}
Within the function, I might want to specify formatting options on the stream. For example, I might want a number to be printed as hex, no matter how the o
is configured when it is passed in to the function.
Secondly, I might want to be able to make assumptions about the current formatting flags. For example, it would be nice to be able to assume that numbers were formatted as decimal unless I request otherwise.
Finally, by the time the function exits I want the formatting options on o
to be the same as they were before the function was called, so as to appear unchanged to the caller. This is simply a matter of politeness to the caller.
Up until now I have achieved this by creating a local ostringstream
within the function, doing all my work on that (including setting formatting options), and sending the .str()
to o
at the end of the function. The StackOverflow question here suggests that people cleverer than me take the same approach. However, it bothers me that I'm keeping so much data in ostringstreams that could perhaps be sent to the output earlier (the strings can get quite large).
I have two questions:
1) Is it legal, idiomatic, good form, etc. to create a temporary (stack based) ostream around o.rdbuf()
and do my work on that ostream? My own tests and the page at cppreference.com appears to suggest that I can.
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) Is there another, better way that I have not considered?