1

我有这个代码:

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();
}

但是,编译器选择了错误的Other::some_function()in重载wtf_func()(即非 const 重载)。我怎样才能解决这个问题?请注意,由于某些原因,我无法更改Other::some_function().

4

5 回答 5

2

o不是 const 限定的,因此some_function选择了非常量。如果要选择 const 限定的重载,则需要将 const 限定符添加到o

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

当重载决议发生时,编译器只查看o.some_function()子表达式;它不会查看函数调用周围的上下文来决定选​​择其他内容。此外,在重载决议期间不考虑成员函数的返回类型。

IntSomething请注意,隐式转换为可能更有意义ConstIntSomething,要么operator ConstIntSomething()在(不太好)中使用重载,要么在IntSomething(更好)中使用非显式ConstIntSomething(IntSomething const&)构造函数ConstIntSomething

于 2011-08-16T18:17:21.980 回答
1

它不会选择错误的重载;const-ness 由是否this存在来解决const。在您的情况下,ois non- const,因此选择了非const重载。

您可以通过创建对 的 const-reference 来解决此问题o,例如:

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

但实际上,您可能应该考虑在Something. 例如,您目前不能这样做:

IntSomething x;
ConstIntSomething y;
y = x;

这听起来不正确。为什么不应该允许您将 const ref 带入 non-const ref?

于 2011-08-16T18:16:47.790 回答
1

您的对象o必须是要在其上调用函数的const对象。const否则编译器会正确选择函数的非 const 版本。

于 2011-08-16T18:17:14.003 回答
0

编译器根据将成为this. 您可以使用以下命令调用所需的版本static_casts = static_cast<const Other&>(o.some_function());

于 2011-08-16T18:21:39.757 回答
0

您可能还想复制在 C++0x 标准库的容器中发现的新行为。诸如vector之类的容器现在具有成员cbegin()并且无论容器是否为const都cend()返回一个const_iteratorbegin()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();
    }
};
于 2011-08-16T18:33:13.330 回答