在回答之前:这不是一个关于如何让这段代码做我想做的事情的问题。我已经知道该怎么做(参见这个问题的结尾)。这是一个关于理解编译器为什么要做它所做的事情的问题。
请考虑以下(简化的)代码:
#include <iostream>
void operator>>( std::istream &stream, char chr )
{
std::cout<<"Called "<<chr<<"\n";
}
int main()
{
char c='b';
std::cin>>c;
return 0;
}
使用 gcc 4.8.2 和 -Wall -Wextra 编译会产生一个不相关的警告(流未使用)。但是,运行时会打印“Called b”。
我预计会发生两件事之一。程序要么从标准输入读取一个字符,要么代码无法编译,因为编译器发现我的运算符和标准库定义的运算符不明确。标准库定义的运算符,根据我的理解,相当于:
std::istream &operator>>( std::istream &stream, char &c )
不管怎样,我都没想到会打电话给我的接线员。
更奇怪的是,由于上面提到的歧义,以下代码无法编译:
#include <iostream>
void function(char &chr)
{
std::cout<<"1 "<<chr<<"\n";
}
void function(char chr)
{
std::cout<<"2 "<<chr<<"\n";
}
int main()
{
char c='a';
function(c);
return 0;
}
除了使用函数而不是运算符之外,我认为编译器对这两种情况的决定没有任何区别。
注意:我完全意识到标准库定义的内容与我上面写的原型并不完全相同。我认为,当涉及到解析函数时,至少在这个用例中,没有什么区别。请记住,std 定义不能有默认参数,因为这是运算符重载。
另外,正如我在问题开头所写的那样,我已经知道如何使代码做正确的事情。使用“const char &”而不是“char”定义运算符会导致编译器选择正确的重载。