2011-06-29 72 views

回答

13

A()爲您提供了一個臨時A對象不是const限定。該A()表達是一個右值表達式,是的,但是這不會使A對象const限定。

由於A對象不是const限定的,因此非const operator int()完全匹配,const operator int()需要進行限定轉換,因此非常量過載被選爲最佳匹配。

如果你希望它是const限定的,你需要明確要求常量限定A

foo(identity<const A>::type()); 

其中identity定義爲

template <typename T> 
struct identity { typedef T type; }; 

注意,有真operator const int() constoperator int() const之間沒有差異:結果是一個右值和唯一的類型右值可以是常量限定(int不是類型)。

另請注意,您所擁有的void foo(const int)void foo(int)之間沒有區別。上參數類型頂層常量-限定符不影響功能的類型(即,這兩個聲明的類型是void foo(int))。除此之外,這是因爲調用者是否有頂級const限定符並不重要;無論如何都必須複製一份。頂級const限定符隻影響函數的定義。

+0

即使'A'是一個正常的堆疊/堆上分配對象(未暫時的),它給出了相同的結果。 – iammilind

+0

如果該對象不是const限定的,則非重載過載在重載解析期間是更好的匹配。有沒有一個理由你會認爲這不是這種情況? –

+0

爲什麼我會感到困惑的是,即使'foo()'接收到'const int'並且我們有一個'A :: operator const int()const'',它仍然會選擇正常的'A :: operator int' 。 – iammilind

4

您必須記住一條有關C++的規則:它從不考慮了選擇過載時返回的值。在這種情況下,因爲operator int函數不帶參數,所以它不能使用參數列表來縮小選擇範圍。它可以使用它所調用的對象的常量。由於這是一個新的臨時對象,因此它不是const的,所以它不會選擇const超載。

+1

* Never *可能太強大;解決超載時會考慮返回類型當函數的地址和解析轉換運算符進行自動轉換時(當後一種函數需要在返回類型上重載時,後者會非常有用,它會返回一個包含不同轉換運算符的代理。) –

5

James McNellis ’答案真的覆蓋了一切,但它沒有’ t傷害(我希望)更多的解釋。

所以。

當你打電話給&hellip;

o.operator int() 

&hellip;那麼過載的選擇完全取決於的恆定性o

沒有別的。

要知道爲什麼,考慮這個類:

struct Bar 
{ 
    void f() {} 
    void f() const {} 
}; 

技術上的成員函數不必是成員函數。他們也可以被選爲自由職業。不過,他們需要Bar說法:

struct Bar 
{}; 

void f(Bar&) {} 
void f(Bar const&) {} 

並希望現在更容易地看到,當你做

Bar o; 
f(o); 

那麼第一個功能可以選擇。就是這樣。因爲如果第二個功能被選中,那麼你永遠不會得到第一個功能。因爲如果您創建對象const,那麼它會破壞const正確性以選擇第一個。所以當對象是const時,只能選擇第二個,因此,當它不是const時,第一個被選中。

總而言之,唯一可行的選擇就是總是選擇第二個,這會使第一個無用,是嗎?

乾杯&第h。,

+0

如果將非const版本設爲私有版本,它仍會嘗試使用該版本而不是公共const版本,從而導致「嘗試訪問私有成員」錯誤!很煩人。 – Oktalist

相關問題