【发布时间】:2018-01-04 19:46:11
【问题描述】:
考虑这段代码:
#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* 重载(因为存在从X 到const wchar_t* 的隐式转换)。
但是,wcout << x 似乎选择了 const void* 重载,而不是 const wchar_t* 一个(打印地址,而不是 wchar_t 字符串)。
这是为什么?
PS 我知道打印X 的正确方法是像wostream& operator<<(wostream& , const X&) 一样实现operator<< 的重载,但这不是问题。
【问题讨论】:
-
这可能不是,但你的程序有undefined behavior。
std::cout和std::wcout不能混搭。 -
@Rakete1111:这不是重点。随意使用 wcout 而不是 cout 来跟踪 f 的选定重载 :)
-
这可能不是重点,但询问为什么具有未定义行为的程序会以某种方式运行没有任何意义,即使在您的情况下它不会改变任何东西。
-
对于那些抱怨混合 wcout 和 cout 的人,我将代码更改为在 f 重载中的跟踪消息中使用 wcout 而不是 cout。相同的输出。
-
注意,打印
const void*的操作符是成员函数,打印const wchar_t*的操作符是非成员函数。我对查找规则不够熟悉,无法说明为什么这很重要,但我很确定它确实如此。
标签: c++ operator-overloading iostream