2011-07-18 12 views
2

私はC++を学び、C++ Primerを使用しています。エクササイズ14.46以下の点を考慮:私はGCC 4.5上記のプログラムを使用してコンパイルするとC++オーバーロードオペレータの解像度

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

、私は

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らしさを除去することに気づいた(4)は、曖昧さがない使用して、正確即ち、

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

と一致します。私はここに何かを逃していますかこの問題を解決するために

答えて

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つのユーザー定義演算子すべてよりも悪いので、どちらも勝てません。

+0

ありがとうございました。私は 'const'修飾子も解決プロセスで役割を果たすことを知らなかった。 – user803563

2

私の好ましい方法は、バージョン1にconstを追加することです:

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