2

私は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+ ?

上記のプログラムのgcc4.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)を使用すると、あいまいさはありません。ここで何かが足りませんか?

4

2 に答える 2

8

次の競合するユーザー定義関数(候補)があります

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

あなたは引数でこれを呼び出しています:

(LongDouble&, double)

最初の議論では、最初の2つの候補が最後の候補よりも優れています。2番目の引数については、最後の候補が最初の2つの候補よりも優れています。少なくとも、すべての引数について他のすべての引数と同じくらい良い一致があり、一部の引数に対してより良い一致がある候補はありません。

この状況の明確な勝者を見つけることはできません。これが私が「十字架」と呼んでいるものです。

ユーザー定義の候補の中から考慮される組み込みの候補もあります。

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

すべての組み込み候補から、operator+(double, double)最もよく一致します。ただし、これには最初の引数のユーザー定義の変換が必要になります。これは、最初の引数の他の3つのユーザー定義の演算子すべてよりも悪いため、どちらにも勝てません。

于 2011-07-18T17:04:17.090 に答える
2

これを修正するための私の好ましい方法はconst、バージョン1に追加することです。

friend LongDouble operator+(const LongDouble&, int);  // (1)
于 2011-07-18T16:59:10.820 に答える