C++ C++;编译器选择类成员函数的错误重载

C++ C++;编译器选择类成员函数的错误重载,c++,overloading,overload-resolution,C++,Overloading,Overload Resolution,我有以下代码: 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)

我有以下代码:

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();
}
模板
分类
{
T值;
公众:
内联某物():val(){}
内联某物(tv):val(v){}
内联T&get()常量{return val;}
inline Something&operator=(const Something&a){val=a.val;返回*this;}
};
输入def某物或某物;
输入def某物构成某物;
其他类
{
公众:
IntSomething some_函数()
{
归还某物(42);
}
constntsomething一些函数()常量
{
归还某物(42);
}
};
void wtf_func()
{
其他o;
便秘;
s=o.某个函数();
}

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

的名称,因为它没有选择错误的重载<代码>常数-通过
是否为
常数来解决不确定性。在您的例子中,
o
是非
const
,因此选择非
const
重载

您可以通过创建对
o
的常量引用来解决此问题,例如:

const Other &o2 = o;
s = o2.some_function();
但实际上,您可能应该考虑
中的重载。例如,您当前无法执行以下操作:

IntSomething x;
ConstIntSomething y;
y = x;

听起来不对。为什么不允许您将常量引用转换为非常量引用?

它不会选择错误的重载<代码>常数
-通过
是否为
常数来解决不确定性。在您的例子中,
o
是非
const
,因此选择非
const
重载

您可以通过创建对
o
的常量引用来解决此问题,例如:

const Other &o2 = o;
s = o2.some_function();
但实际上,您可能应该考虑
中的重载。例如,您当前无法执行以下操作:

IntSomething x;
ConstIntSomething y;
y = x;

听起来不对。为什么不允许您将常量ref转换为非常量ref?

您的对象
o
必须是
const
对象,才能对其调用
const
函数。否则,编译器将正确地选择函数的非常量版本。

您的对象
o
必须是
const
对象,才能对其调用
const
函数。否则,编译器会正确地选择函数的非常量版本。

o
不是常量限定的,因此会选择非常量
某个函数。如果要选择常量限定重载,需要将常量限定符添加到
o

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


请注意,
IntSomething
可以隐式转换为
constntsomething
,在
IntSomething
中使用
操作符constntsomething()
重载(不太好)或使用非显式的
constmentsomething(IntSomething const&)
构造函数在
组件中
(更好)。

o
不符合常量,因此选择了非常量
某些函数
。如果要选择常量限定重载,需要将常量限定符添加到
o

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


请注意,
IntSomething
可以隐式转换为
constntsomething
,在
IntSomething
中使用
操作符constntsomething()
重载(不太好)或使用非显式的
constmentsomething(IntSomething const&)
construtsomething
(更好)中的构造函数。

编译器根据将成为
this
的对象的常量选择要使用的重载。您可以使用
static\u cast
s=static\u cast(o.some\u function())使其调用所需的版本

编译器根据将成为
this
的对象的常量选择要使用的重载。您可以使用
static\u cast
s=static\u cast(o.some\u function())使其调用所需的版本

您可能还希望复制在C++0x标准库的容器中发现的新行为。像vector这样的容器现在有成员
cbegin()
cend()
,它们返回一个常量迭代器,无论容器是否为常量,这与
begin()
end()


您可能还希望复制在C++0x标准库的容器中发现的新行为。像vector这样的容器现在有成员
cbegin()
cend()
,它们返回一个常量迭代器,无论容器是否为常量,这与
begin()
end()


这有点误导,因为您可以使用带有
const
成员函数的非
const
对象,并且您可以调用它们。@Seth Carnegie:是的,只是为了澄清一下。您可以在非常量对象上调用常量成员函数,但不能在常量对象上调用非常量成员函数。这有点误导,因为您可以使用
const
成员函数调用非
const
对象。@Seth Carnegie:是的,只是为了澄清一下。可以在非常量对象上调用常量成员函数,但不能调用非常量me