2011-08-16 56 views
1

的錯過載我有這樣的代碼:C++編譯器選擇一個類的成員函數

template <class T> 
class Something 
{ 
    T val; 
public: 
    inline Something() : val() {} 
    inline Something(T v) : val(v) {} 
    inline T& get() const { return val; } 

    inline Something& operator =(const Something& a) { val = a.val; return *this; } 
}; 

typedef Something<int> IntSomething; 
typedef Something<const int> ConstIntSomething; 

class Other 
{ 
public: 
    IntSomething some_function() 
    { 
     return IntSomething(42); 
    } 

    ConstIntSomething some_function() const 
    { 
     return ConstIntSomething(42); 
    } 
}; 

void wtf_func() 
{ 
    Other o; 
    ConstIntSomething s; 
    s = o.some_function(); 
} 

但是,編譯器拾取的在wtf_func()Other::some_function()錯誤的過載(即,非const之一)。我怎樣才能解決這個問題?請注意,由於某些原因,我無法更改Other::some_function()的名稱。

回答

2

o不是const限定的,所以選擇非const some_function。如果你想選擇的const限定過載,你需要const限定符添加到o

Other o; 
Other const& oref(o); 
ConstIntSomething s; 
s = oref.some_function(); 

當重載決議時,編譯器只着眼於o.some_function()子表達式;它並沒有考慮函數調用的上下文來決定選​​擇其他的東西。此外,在重載解析期間不考慮成員函數的返回類型。

注意,可能更有意義IntSomething是隱式轉換爲ConstIntSomething,或者使用在IntSomething(不太好的)的operator ConstIntSomething()過載或ConstIntSomething(多好)使用非明確ConstIntSomething(IntSomething const&)構造函數。

1

它沒有選擇錯誤的過載; const的性質由this是否爲const來解決。在你的情況下,o是非const,所以非const過載被挑選。

您可以通過給o創建一個const引用破解此,例如:

const Other &o2 = o; 
s = o2.some_function(); 

但實際上,你可能應該考慮Something你的重載。例如,你目前不能這樣做:

IntSomething x; 
ConstIntSomething y; 
y = x; 

這聽起來不正確。爲什麼你不應該被允許對一個非const的ref做一個const ref?

1

您的對象o需要const對象const函數被調用它。否則,編譯器會正確地獲取該函數的非常量版本。

+0

這是一個有點誤導,因爲你可以有'常量非'const'對象'會員功能,你可以給他們打電話。 –

+0

@Seth Carnegie:沒錯,只是爲了說清楚。你可以在非const對象上調用const成員函數,但是你不能在const對象上調用非const成員函數。 –

0

編譯器根據將變爲this的對象的常量選擇要使用的超載。您可以使用static_cast來調用期望的版本:s = static_cast<const Other&>(o.some_function());

0

您可能還想複製在C++ 0x標準庫的容器中找到的新行爲。容器如矢量現在有返回的const_iterator成員cbegin()cend()容器是否是const或沒有什麼不同begin()end()

class Other { 
    // Rest of other 
public: 
    // No overload for non-const 
    // Even if called with a non const Other, since this member is marked 
    // const, this will be of type Other const * in all cases and will call 
    // the const qualified overload of some_function. 
    ConstIntSomething csome_function() const 
    { 
     return some_function(); 
    } 
}; 
相關問題