Subject: Re: behaviour change in operator<<
Date: Wed, 13 Aug 2003 13:23:36 -0500
Message-ID: <
[email protected]>
References: <
[email protected]>
Carlo said:
I found a change in the following code, that behaved
correctly in VC++ 6.
#include <strstream>
using namespace std;
void main()
{
char x[100];
ostrstream(x, 100) << "pippo" << "pluto" << ends;
// here x contains "004400C8pluto"
}
Clearly,
basic_ostream:
perator<<(const void*)
have been called, instead of
basic_ostream:
perator<<(const char*).
Some change in scoping rule (due to the introduction of
Koenig Lookup) justify this change?
Many Thanks for your attention.
It's not a bug. There is a member output operator for void*, but the char*,
signed char*, and unsigned char* output operators are non-members whose
first parameter is a non-const ostream&. The compiler is choosing the member
operator, because you can call member functions through temporary objects,
e.g. X().f(), or here, ostream().operator<<("pippo"), but you can't bind
temporaries to non-const references, which eliminates the non-member
operators. So:
ostrstream(x, 100) << "pippo" << "pluto" << ends;
calls the operator<<(const void*) member and stores a pointer value[1],
while:
ostrstream os(x, 100);
os << "pippo" << "pluto" << ends;
calls the non-member operator<<(ostream&, const char*) and stores the
strings.
The craziest thing is that this is apparently the way it's supposed to work.
The non-member operators<< are rejected in the first case as non-viable,
because selecting them would require binding a temporary to a non-const
reference, leaving the member operator<<(const void*) to handle the output
of the string literal. FWIW, I'm not convinced it makes sense to eliminate
functions from overload resolution based on the reference binding issue, but
that's what the standard says.
[1] The string "pluto" is stored after the address of "pippo", because
operator<< returns ostream&, and there's no problem binding it to the first
parameter of operator<<(ostream&, const char*).