"Igor Tandetnik" wrote:
Looks like a bug. I see no reason why the two output statements
shouldn't behave identically.
Could it be because of the requirement of more implicit
conversions to be performed for second case? Consider:
template<typename T1, typename T2>
int operator<<(T1& x, const T2*) { return 0; }
struct X
{
int operator<<(const void*) { return 0; }
};
struct Y
{
operator const wchar_t*() { return NULL; }
};
const wchar_t* f() { return NULL; }
...
X x;
// 1. X::operator<< is considered.
// 2. X::operator<< parameters don't match.
// 3. Tempalte ::operator<< is considered.
// 4. Exact match with ::operator<X, wchar_t> <<
x << f();
// 1. X::operator<< is considered.
// 2. X::operator<< parameters don't match.
// 3. Tempalte ::operator<< is considered.
// 4. Tempalte ::operator<< doesn't match.
// 5. X::operator<< will match after user-defined
// conversion of an argument.
// 6. Calls user-defined operator;
// calls X::operator<<.
x << Y();
So, in order to match the "Y()" expression against global
`operator<<' template the compiler would have been required not
only to abandon `X::operator<<' in favor of weaker global
template, but also to perform a user-defined conversion in any
case. Therefore, the stronger candidate `X::operator<<' with
user-defined conversion wins.
Yeah, just about.
It's a bit stronger than that, though: the template doesn't participate any more
after it's been established that there's no exact match. I.e. the "weaker"
match is simply a complete no-match. Consider:
foo( S() ); // No match, error.
See also my post else-thread about possible defect in the standard (inconsistent
behavior for char const* versus wchar_t const* argument) else-thread.
A: Because it messes up the order in which people normally read text.
A: Top-posting.