c ++重载运算符解析

时间:2011-07-18 16:57:38

标签: c++ overload-resolution

我正在学习c ++并使用C ++ Primer。请考虑以下练习14.46:

 class Complex {
     Complex(double);
     // ...
 };

 class LongDouble {

     friend LongDouble operator+(LongDouble&, int);  // (1)

 public:
     LongDouble(int);

     operator double();

     LongDouble operator+(const Complex &);  // (2)
     // ...
  };

 LongDouble operator+(const LongDouble &, double);  // (3)

 LongDouble ld(16.08);
 double res = ld + 15.05; // which operator+ ?

当我使用gcc 4.5编译上面的程序时,我得到了

14_46.cpp:60:21: error: ambiguous overload for ‘operator+’ in ‘ld + 1.5050000000000000710542735760100185871124267578125e+1’
14_46.cpp:60:21: note: candidates are: operator+(double, double) <built-in>
14_46.cpp:35:5: note:                 LongDouble LongDouble::operator+(const Complex&)
14_46.cpp:45:1: note:                 LongDouble operator+(const LongDouble&, double)
14_46.cpp:17:5: note:                 LongDouble operator+(LongDouble&, int)

为什么(3)没有被选中?这不完全匹配吗?

但是,我注意到删除(3)中参数的常数完全匹配,即

LongDouble operator+(LongDouble &, double);  // (4)

使用(4)没有歧义。我在这里错过了什么吗?

2 个答案:

答案 0 :(得分:8)

您有以下竞争用户定义的功能(候选人)

operator+(LongDouble&, int); // friend
operator+(LongDouble&, Complex const&); // member
operator+(LongDouble const&, double); // global

你用参数调用它:

(LongDouble&, double)

对于第一个参数,前两个候选者比最后一个好。对于第二个参数,最后一个候选者比前两个候选者更好。对于所有参数,没有候选人至少与所有其他候选人一样好,并且对于某些参数更好地匹配。

你无法找到这种情况的明显赢家。这就是我所谓的“纵横交错”。

还有一些内置候选人被认为是用户定义的候选人。

operator+(double, double);
operator+(int, double);
...

从所有内置候选人中,operator+(double, double)最匹配。但是这需要第一个参数的用户定义转换,这比第一个参数的所有其他三个用户定义的运算符更糟糕,所以它也不能获胜。

答案 1 :(得分:2)

我解决此问题的首选方法是将const添加到版本1:

friend LongDouble operator+(const LongDouble&, int);  // (1)