在这种情况下,为什么朋友重载运算符优先于转换运算符

时间:2010-03-13 18:07:26

标签: c++ operator-overloading implicit-conversion

嗨我有这样的代码,我认为朋友重载的运算符和转换运算符都有类似的功能。但是,为什么在这种情况下会调用朋友重载运算符?规则是什么?

非常感谢!

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;
      }
}

4 个答案:

答案 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,则调用将会变得模棱两可,因为中性路径将优于其他路径。