2011-08-16 38 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(); 
    } 
}; 
相关问题