Reputation: 501
I use std::ostringstream
for formatting strings, which inherits its <<
operators from ostream
, and consequently they return an ostream
and not an ostringstream
, which means that I can't call ostringstream::str
on the result. This usually isn't a problem, since I can typically do this:
ostringstream stream;
stream << whatever;
string str = stream.str();
But occasionally I need* to use it in just a single expression, which is more difficult. I could do
string str = ((ostringstream&) (ostringstream() << whatever)).str();
but bad things will happen if that <<
overload returns some ostream
that isn't an ostringstream
. The only other thing I can think to do is something like
string str = ([&] () -> string {ostringstream stream; stream << whatever; return stream.str();})();
but this can't possibly be efficient, and is certainly very bad c++ code.
*Okay, I don't need to, but it would be a lot more convenient to.
Upvotes: 4
Views: 1039
Reputation: 153840
Assuming you got
std::string get_str(std::ostream& out) {
retrun static_cast<std::stringbuf*>(out.rdbuf())->str();
}
You could use
std:: string s = get_str(std::ostringstream{} << ...);
Upvotes: 1
Reputation: 206607
Using
string str = ([&] () -> string
{
ostringstream stream;
stream << whatever;
return stream.str();
})();
is ok. However, I think it will be better to name that operation, create a function with that name, and call the function.
namespace MyApp
{
template <typename T>
std::string to_string(T const& t)
{
ostringstream stream;
stream << t;
return stream.str();
}
}
and then use
string str = MyApp::to_string(whatever);
Upvotes: 3
Reputation: 25327
The only other thing I can think to do is something like
string str = ([&] () -> string {ostringstream stream; stream << whatever; return stream.str();})();
but this can't possibly be efficient, and is certainly very bad c++ code.
Actually, no. Once the optimizer has a look at this, it's exactly as fast as the original code. And it's not "very bad c++ code". It's known as an Immediately Invoked Lambda Expression, or IILE. It's an idiom, and actually quite decent practice.
It would be better formatted more like this, though:
// One of the benefits of IILEs is that `const` can be used more frequently
string const str = [&] {
ostringstream stream;
stream << whatever;
return stream.str();
}();
Some people prefer using std::invoke
to invoke the lambda instead:
string const str = std::invoke([&] {
ostringstream stream;
stream << whatever;
return stream.str();
});
Upvotes: 2