嗨我有这样的代码,我认为朋友重载的运算符和转换运算符都有类似的功能。但是,为什么在这种情况下会调用朋友重载运算符?规则是什么?
非常感谢!
class A{
double i;
public:
A(int i):i(i) {}
operator double () const { cout<<"conversion operator"<<endl;return i;} // a conversion operator
friend bool operator>(int i, A a); // a friend funcion of operator >
};
bool operator>(int i, A a ){
cout<<"Friend"<<endl;
return i>a.i;
}
int main()
{
A aa(1);
if (0 > aa){
return 1;
}
}
答案 0 :(得分:4)
无需转换即可调用重载的operator>
。为了调用内置operator>
,需要进行一次转换(用户定义的转换运算符。重载解析更喜欢需要转换次数较少的选项,因此会使用重载的operator>
。
请注意,如果您要将重载operator>
的定义更改为,例如:
friend bool operator>(double i, A a);
您会收到编译错误,因为重载的operator>
和内置的operator>
都需要一次转换,编译器无法解决这种歧义。
答案 1 :(得分:1)
我并不是说我的答案得到了标准的支持,但让我们从逻辑上考虑一下。
当你点击这一行时:
0 > aa
您有两种选择。您可以调用提供的运算符:
friend bool operator>(int i, A a);
哪个是100%兼容,或者您可以进行两次转换以到达目的地!你会选择哪一个?
答案 2 :(得分:0)
如果添加转换运算符,那么类型A的对象可能会在您最不期望的时候转换为double。
一个好的程序没有为他的类提供一种意外使用的方法,并且转换操作符打开了在一系列非预期情况下使用的类的机会(通常情况下你会期望编译时错误不是因为自动类型转换。)
因此,转换操作符(和单个参数构造函数)应该小心处理,因为编译器可能会在您最不期望的情况下进行转换。
答案 3 :(得分:0)
调用它是因为它在表达式0 > aa
的上下文中是完全匹配。事实上,很难弄清楚你是如何想出“为什么”的问题。根据逻辑,在这种情况下,如果朋友未被调用,则会有一个“为什么”的问题。
如果将表达式更改为0.0 > aa
,则调用将会变得模棱两可,因为中性路径将优于其他路径。