This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]