为什么<iostream> operator <<选择明显错误的重载?

Mr.*_*C64 8 c++ iostream operator-overloading

考虑以下代码:

#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;
}
Run Code Online (Sandbox Code Playgroud)

输出是(使用VS2015 C++编译器编译):

f(const wchar_t*)
00118B30
Run Code Online (Sandbox Code Playgroud)

因此,似乎编译器选择了预期的 const wchar_t*重载f(因为存在从内X到的隐式转换const wchar_t*).

但是,它似乎wcout << x选择了const void*重载,而不是const wchar_t*一个(打印地址,而不是wchar_t字符串).

为什么是这样?

PS我知道正确的打印方式X是实现operator<<类似的重载wostream& operator<<(wostream& , const X&),但这不是问题的关键.

Max*_*kin 4

因为在推导模板参数时不考虑转换函数:

// 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 );
Run Code Online (Sandbox Code Playgroud)

第二个声明不考虑转换operator const wchar_t* () const

我找不到标准引用,cppreference 模板参数推导,隐式转换说:

类型推导不考虑隐式转换(除了上面列出的类型调整之外):这是重载解析的工作,稍后发生。

  • 如果删除非模板,它甚至不会编译,因为模板参数推导不会发生隐式转换。:) (3认同)