为什么<iostream>运算符&lt;&lt;选择明显错误的超载?

时间:2017-07-28 16:43:02

标签: c++ operator-overloading iostream

考虑以下代码:

var jsonObj = {"first name" : "fname"}

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

#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;
}

因此,编译器似乎为f(const wchar_t*) 00118B30 选择了预期的 const wchar_t*重载(因为它是从f到{{的隐式转换1}})。

但是,似乎X选择const wchar_t*重载,而不是wcout << x重载(打印地址,而不是const void*字符串)。

为什么会这样?

PS 我知道正确的打印方式const wchar_t*是实现wchar_t的重载,例如X,但不是< / em>问题的关键点。

1 个答案:

答案 0 :(得分: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 );

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

我找不到标准报价,cppreference Template argument deduction, Implicit conversions说:

  

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