在回答之前:这不是关于如何让这段代码做我想做的事情的问题.我已经知道如何做到这一点(见本问题的结尾).这是一个关于理解编译器为什么会这样做的问题.
请考虑以下(简化)代码:
#include <iostream>
void operator>>( std::istream &stream, char chr )
{
std::cout<<"Called "<<chr<<"\n";
}
int main()
{
char c='b';
std::cin>>c;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
用gcc 4.8.2和-Wall -Wextra编译产生一个无关警告(流未使用).但是,在运行时,打印"Called b".
我预计会发生两件事之一.程序将从标准输入中读取一个字符,否则代码将无法编译,因为编译器发现我的运算符和标准库定义的运算符不明确.根据我的理解,标准库定义的运算符相当于:
std::istream &operator>>( std::istream &stream, char &c )
Run Code Online (Sandbox Code Playgroud)
无论哪种方式,我都没想到我的操作员会被调用.
更奇怪的是,由于上面提到的含糊不清,以下代码无法编译:
#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;
}
Run Code Online (Sandbox Code Playgroud)
除了使用函数而不是运算符之外,我认为编译器对这两种情况的决定没有任何区别.
注意:我完全意识到标准库定义的内容与我上面编写的原型不完全相同.我认为,在解决功能时,至少在这个用例中,重要的是没有区别.请记住,std定义不能有默认参数,因为这是一个运算符重载.
另外,正如我在问题的开头写的那样,我已经知道如何使代码做正确的事情.使用"const char&"而不是"char"定义我的运算符会导致编译器选择正确的重载.
对于呼叫std::cin>>c;,有两个可行的功能.你宣布的那个
void operator>>( std::istream &stream, char chr );
Run Code Online (Sandbox Code Playgroud)
和流库中定义的那个(作为函数模板的特化):
template< class CharT, class Traits >
basic_istream<CharT,Traits>& operator>>( basic_istream<CharT,Traits>& st, CharT& ch );
Run Code Online (Sandbox Code Playgroud)
选择最终获得重载决策的最佳可行功能如下所述13.3.3 [over.match.best]:
1 De fi ne ICSi(F)如下:
- 如果F是静态成员函数,则定义ICS1(F)使得ICS1(F)对于任何函数G既不比ICS1(G)更好也不差,并且对称地,ICS1(G)既不好也不差ICS1(F); 除此以外,
- 让ICSi(F)表示隐式转换序列,它将列表中的第i个参数转换为可行函数F的第i个参数的类型.13.3.3.1定义隐式转换序列,13.3.3.2定义它是什么表示一个隐式转换序列比另一个更好的转换序列或更差的转换序列.
鉴于这些定义,如果对于所有参数i,ICSi(F1)不是比ICSi(F2)更差的转换序列,则可行函数F1被定义为比另一个可行函数F2更好的函数,然后
- 对于某些参数j,ICSj(F1)是比ICSj(F2)更好的转换序列,或者,如果不是,
- 上下文是用户定义的转换初始化(见8.5,13.3.1.5和13.3.1.6)以及从返回类型F1到目标类型的标准转换序列(即,正在初始化的实体的类型)是一个比从F2的返回类型到目标类型的标准转换序列更好的转换序列.
[示例:省略 ]或者,如果不是,- F1是非模板函数,F2是函数模板特化,或者,如果不是,
- F1和F2是功能模板特化,根据14.5.6.2中描述的偏序规则,F1的功能模板比F2的模板更专业.
2如果只有一个可行的函数比所有其他可行函数更好的函数,则它是由重载决策选择的函数; 否则电话会形成不良.
为了简化它 - 在其他条件相同的情况下,非模板比模板特化更好.
在示例中function,候选人之间没有这种区别.调用所需的两个隐式转换序列(char- > char&和char- > char)都是身份转换,并且不明确.
| 归档时间: |
|
| 查看次数: |
380 次 |
| 最近记录: |