2011-07-18 44 views
2

我正在學習C++並使用C++ Primer。考慮下面的練習14.46: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+ ? 

當我編譯使用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)沒有歧義。我在這裏錯過了什麼嗎?

回答

8

有以下幾個相互競爭的用戶自定義函數(候選人)

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

你用參數調用這個:

(LongDouble&, double) 

對於第一個參數,前兩個念珠菌tes比上次更好。對於第二個參數,最後一個候選人比前兩個候選人要好。沒有一個候選人與所有其他參賽者的所有參數都有至少一樣好的匹配,並且有些參數匹配得更好。

你無法弄清楚這種情況的明確贏家。這就是我所稱的「十字交叉」。

也有內建候選人被認爲是用戶定義的候選人。

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

從所有的內建候選人中,operator+(double, double)最匹配。但是這將需要用戶爲第一個參數定義的轉換,這比第一個參數的所有其他三個用戶定義的運算符都差,因此它也不能獲勝。

+0

謝謝。我不知道'const'限定詞在解析過程中也起了一定的作用。 – user803563

2

我來解決這個首選的方法是添加const 1版本:

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