I have stumbled on a weird behavior that I just could not explain at first (see ideone):
#include <iostream>
#include <sstream>
#include <string>
int main() {
std::cout << "Reference : "
<< (void const*)"some data"
<< "\n";
std::ostringstream s;
s << "some data";
std::cout << "Regular Syntax: " << s.str() << "\n";
std::ostringstream s2;
std::cout << "Semi inline : "
<< static_cast<std::ostringstream&>(s2 << "some data").str()
<< "\n";
std::cout << "Inline : "
<< dynamic_cast<std::ostringstream&>(
std::ostringstream() << "some data"
).str()
<< "\n";
}
Gives the output:
Reference : 0x804a03d
Regular Syntax: some data
Semi inline : some data
Inline : 0x804a03d
Surprisingly, in the last cast we have the address, and not the content!
Why is that so ?
The expression
std::ostringstream()creates a temporary, andoperator<<which takesconst char*as argument is a free function, but this free function cannot be called on a temporary, as the type of the first parameter of the function isstd::ostream&which cannot be bound to temporary object.Having said that,
<<std::ostringstream() << "some data"resolves to a call to a member function which is overloaded forvoid*which prints the address. Note that a member function can be invoked on the temporary.In order to call the free function, you need to convert temporary (which is rvalue) into a lvalue, and here is one trick that you can do:
That is,
std::ostringstream().flush()returnsstd::ostream&which means, now the free function can called, passing the returned reference as first argument.Also, you don’t need to use
dynamic_casthere (which is slow, as it is done at runtime), for the type of the object is pretty much known, and so you can usestatic_cast(which is fast as it is done at compile-time):which should work just fine.