Re: How to build a string on the fly, using std::ostringstream?
On Apr 23, 8:14 pm, "Niels Dekker - no return address"
<nore...@this.is.invalid> wrote:
std::string s = (std::ostringstream() << "i = " << i).str();
Of course it didn't compile, because a temporary (std::ostringstream())
cannot
be passed as non-const reference to a function (operator<<).
Well, that is not the case on the implementations I use (VC7.1/VC9.0).
The << operator is implemented as a member of ostream; which does bind
to temporaries; so this works fine:
ostringstream () << "i = " << i; // compiles
I don't know if the standard mandates this or not though.
Unfortunately it still didn't compile, because operator<< returns an
std::basic_ostream, instead of an std::ostringstream, and therefore it
doesn't
have an str() member function.
Yes, the reason it doesn't work is type erasure. The first application
of << returns ostream&, and ostringstream::str can not be applied to
an ostream.
Now I wonder, is it safe to cast the stream, returned by operator<< to an
ostringstream reference?
Yes, you can recover the type in this way, but pedantically you should
use a dynamic_cast to do so.
dynamic_cast <ostringstream&> (ostringstream () << ...).str ();
This is ugly and verbose though. An alternative wrapper solution that
I use is based on forwarding the << operator call:
struct S { // string builder
std::ostringstream s;
template <typename T>
inline S& operator << (const T& v) {
using ::operator <<; // Note: Ugly disambiguation.
s << v;
return *this;
}
inline operator std::string () const
{return s.str ();}
};
Usage:
string s = S () << "i = " << i;
This works for me in practice. But you may stumble into problems
caused by less-than-perfect forwarding (e.g. ambiguities). I haven't
studied the best solution to this yet.
Regards,
Vidar Hasfjord
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]