c++重载操作符解析

c++ overload operator resolution

本文关键字:操作符 重载 c++      更新时间:2023-10-16

我正在学习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)中删除参数的const-ness完全匹配,即

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

使用(4)没有歧义。我遗漏了什么吗?

您有以下相互竞争的用户定义函数(候选函数)

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)是最匹配的。但是,这需要对第一个实参进行用户定义的转换,这比第一个实参的所有其他三个用户定义的操作符更糟糕,因此它也不能获胜。

解决这个问题的最佳方法是将const添加到版本1:

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