This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Strange behavoiur of ostringstream (tested on g++3.3.5/4.0.2)
- From: Wladimir Mutel <mwg at mwg dot dp dot ua>
- To: libstdc++ at gcc dot gnu dot org
- Date: Sat, 28 Jan 2006 11:14:40 +0200
- Subject: Strange behavoiur of ostringstream (tested on g++3.3.5/4.0.2)
Dear people,
Here is my sample :
#include <iostream>
#include <sstream>
using namespace std;
#define SFORMAT(e) ((dynamic_cast<const ostringstream&>(ostringstream() << e)).str())
int main(int argc, char* argv[])
{
cout << SFORMAT("2 x " << " 2 = " << 2*2);
return 0;
}
When I compile and run it, the first string constant ("2 x ") is
printed as pointer in hexadecimal form. The second constant
(" 2 = ") prints as it should.
ltrace shows that first one is printed by
__ostream_type& operator<<(const void* __p);
(g++4.0.2, header "ostream", line 224,
it's a member of basic_ostream)
and second - by
template<typename _CharT, typename _Traits> basic_ostream<_CharT, _Traits> & operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s);
(line 485 or 481 in the same header,
it's out-of class template inserter).
The question is how to overcome this strange lookup.
I suspect that for the compiler, newly-constructed
ostringstream() is of type "ostringstream", and result of
ostringstream() << "string" is of type "ostringstream&", so
lookup rules are different in this case. But why they should be
different, and why the compiler can not upcast "ostringstream" to
"ostringstream&" and lookup "the proper" function for <<(char*) ?
Btw, in MS VC++ .NET-2003 I managed to reproduce the same
behaviour, but worked around this problem by adding helper
function :
template <class C> inline C& ref(C& c) {return c;}
#define SFORMAT(e) ((dynamic_cast<const ostringstream&>(ref(ostringstream()) << e)).str())
Unfortunately G++ refused to compile this code. May be it more
strictly obeys semantic restrictions and does not do some
obvious analysis than VC++ did.
So, dear people, I would appreciate if you clear my possible
misconceptions about C++, refer me to the knowledgeable
authority able to give final answer on my question, or propose
a workaround that is portable and not specific to VC++.
Thank you in advance for your replies.