Consider this code:
#include <iostream>
using namespace std;
class X {
public:
operator const wchar_t* () const { return L"Hello"; }
};
void f(const void *) {
wcout << L"f(const void*)\n";
}
void f(const wchar_t*) {
wcout << L"f(const wchar_t*)\n";
}
int main() {
X x;
f(x);
wcout << x;
}
The output is (compiled with the VS2015 C++ compiler):
f(const wchar_t*) 00118B30
So it seems that the compiler selects the expected const wchar_t*
overload for f
(as there's an implicit conversion from X
to const wchar_t*
).
However, it seems that wcout << x
picks the const void*
overload, instead of the const wchar_t*
one (printing an address, instead of a wchar_t
string).
Why is this?
P.S. I know that the proper way of printing X
is to implement an overload of operator<<
like wostream& operator<<(wostream& , const X&)
, but that is not the point of the question.
Because when deducing template arguments the conversion functions are not considered:
// Non-template member function.
basic_ostream& basic_ostream::operator<<( const void* value );
// Template non-member function.
template< class CharT, class Traits >
basic_ostream<CharT,Traits>& operator<<( basic_ostream<CharT,Traits>& os,
const CharT* s );
The second declaration does not consider the conversion operator const wchar_t* () const
.
I cannot find the standard quote, cppreference Template argument deduction, Implicit conversions says:
Type deduction does not consider implicit conversions (other than type adjustments listed above): that's the job for overload resolution, which happens later.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With