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()
重载(即非常量重载)。我该如何解决这个问题?请注意,由于某些原因,我无法更改 Other::some_function()
的名称。
I have this code:
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();
}
However, the compiler picks the wrong overload of Other::some_function()
in wtf_func()
(i.e. the non-const one). How can I fix this? Note that for certain reasons I cannot change the name of Other::some_function()
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
o
不是 const 限定的,因此选择非 constsome_function
。如果要选择 const 限定的重载,则需要在o
上添加 const 限定符:当重载决策发生时,编译器只查看
o.some_function()
> 子表达式;它不会查看函数调用周围的上下文来决定选择其他内容。此外,在重载决策期间不考虑成员函数的返回类型。请注意,将
IntSomething
隐式转换为ConstIntSomething
可能更有意义,可以使用IntSomething 中的
(不太好)或使用非显式的operator ConstIntSomething()
重载ConstIntSomething(IntSomething const&)
构造函数ConstIntSomething
(更好)。o
is not const-qualified, so the non-constsome_function
is selected. If you want to select the const-qualified overload, you need to add the const qualifier too
:When overload resolution occurs, the compiler only looks at the
o.some_function()
subexpression; it does not look at the context around the function call to decide to pick something else. Further, the return type of a member function is not considered during overload resolution.Note that it may make more sense for
IntSomething
to be implicitly convertible toConstIntSomething
, either using anoperator ConstIntSomething()
overload inIntSomething
(less good) or using a non-explicitConstIntSomething(IntSomething const&)
constructor inConstIntSomething
(more good).它不会选择错误的过载;
const
-ness 通过this
是否为const
来解析。在您的情况下,o
是非const
,因此选择非const
重载。您可以通过创建对
o
的常量引用来破解此问题,例如:但实际上,您可能应该考虑
Something
中的重载。例如,您目前无法执行此操作:这听起来不正确。为什么不应该允许您将 const 引用传递给非常量引用?
It doesn't pick the wrong overload;
const
-ness is resolved by whetherthis
isconst
or not. In your case,o
is non-const
, so the non-const
overload is picked.You can hack this by creating a const-reference to
o
, e.g.:But really, you should probably be considering your overloads in
Something
. For instance, you can't currently do this:which doesn't sound correct. Why shouldn't you be allowed to take a const ref to a non-const ref?
您的对象
o
必须是const
对象,才能在其上调用const
函数。否则,编译器会正确地选择该函数的非 const 版本。Your object
o
needs to beconst
object for aconst
function to be called on it. Otherwise the compiler rightly picks up the non const version of the function.编译器根据将成为
this
的对象的常量性来选择要使用的重载。您可以使用static_cast
使其调用所需的版本:s = static_cast(o.some_function());
The compiler picks the overload to use based on the constness of the object that will become
this
. You can make it call the desired version withstatic_cast
:s = static_cast<const Other&>(o.some_function());
您可能还想复制 C++0x 标准库容器中的新行为。像 Vector 这样的容器现在具有成员
cbegin()
和cend()
,无论容器是否为 const,它们都会返回 const_iterator,这与begin()
不同和end()
You might also want to copy the new behaviour found in the containers of the C++0x standard library. Containers such as vector now have members
cbegin()
andcend()
that return a const_iterator whether the container is const or not unlikebegin()
andend()