为什么 <iostream> operator<< 选择明显错误的重载?
Why does <iostream> operator<< pick the apparently wrong overload?
考虑这段代码:
#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;
}
输出为(使用VS2015 C++编译器编译):
f(const wchar_t*)
00118B30
所以编译器似乎为 f
选择了 expected const wchar_t*
重载(因为存在从 X
到 const wchar_t*
).
但是,wcout << x
似乎选择了 const void*
重载,而不是 const wchar_t*
重载(打印地址,而不是 wchar_t
字符串)。
这是为什么?
P.S. 我知道打印 X
的正确方法是实现 operator<<
的重载,例如 wostream& operator<<(wostream& , const X&)
,但这不是问题的重点。
因为在推导模板参数时不考虑转换函数:
// 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 );
第二次声明不考虑转换operator const wchar_t* () const
.
我找不到标准报价,cppreference Template argument deduction, Implicit conversions 说:
Type deduction does not consider implicit conversions (other than type adjustments listed above): that's the job for overload resolution, which happens later.
考虑这段代码:
#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;
}
输出为(使用VS2015 C++编译器编译):
f(const wchar_t*) 00118B30
所以编译器似乎为 f
选择了 expected const wchar_t*
重载(因为存在从 X
到 const wchar_t*
).
但是,wcout << x
似乎选择了 const void*
重载,而不是 const wchar_t*
重载(打印地址,而不是 wchar_t
字符串)。
这是为什么?
P.S. 我知道打印 X
的正确方法是实现 operator<<
的重载,例如 wostream& operator<<(wostream& , const X&)
,但这不是问题的重点。
因为在推导模板参数时不考虑转换函数:
// 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 );
第二次声明不考虑转换operator const wchar_t* () const
.
我找不到标准报价,cppreference Template argument deduction, Implicit conversions 说:
Type deduction does not consider implicit conversions (other than type adjustments listed above): that's the job for overload resolution, which happens later.