为什么<iostream>运算符<<会选择明显错误的重载?

Why does <iostream> operator<< pick the apparently wrong overload?

本文关键字:lt 错误 重载 iostream gt 运算符 为什么 选择      更新时间:2023-10-16

请考虑以下代码:

#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选择了预期的const wchar_t*重载(因为存在从Xconst wchar_t*的隐式转换(。

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

这是为什么呢?

附言我知道打印X的正确方法是实现像wostream& operator<<(wostream& , const X&)这样的operator<<重载,但这不是问题的重点。

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

// 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

我找不到标准报价,cpp首选项模板参数推导,隐式转换 说:

类型

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