C++编译器选择类成员函数的错误重载
C++ compiler picking the wrong overload of a class member function
我有这个代码:
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()
的名称。
o
不是常量限定的,因此选择了非常量some_function
。 如果要选择常量限定的重载,则需要将常量限定符添加到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&)
构造函数(更好(。
它不会选择错误的重载; const
-ness 由this
是否const
来解决。 在您的情况下,o
是非const
,因此选择非const
重载。
您可以通过创建对o
的常量引用来破解它,例如:
const Other &o2 = o;
s = o2.some_function();
但实际上,您可能应该考虑Something
中的过载。 例如,您当前无法执行此操作:
IntSomething x;
ConstIntSomething y;
y = x;
这听起来不正确。 为什么不应该允许你把一个常量引用带到一个非常量引用?
您的对象o
需要const
对象才能在其上调用const
函数。 否则,编译器会正确选取函数的非 const 版本。
将变得this
的对象的恒定性来选择要使用的重载。您可以使用static_cast
: s = static_cast<const Other&>(o.some_function());
还想复制在 C++0x 标准库的容器中找到的新行为。像 vector 这样的容器现在具有成员cbegin()
和cend()
,它们返回一个const_iterator,无论容器是否是常量,这与 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();
}
};
- 错误 没有与参数列表匹配的重载函数"getline"实例
- 在运算符重载定义中使用成员函数(const错误)
- 重载方法的方式会在使用临时调用时生成编译器错误
- 数组索引重载错误
- C++:需要帮助了解运算符重载错误
- 在类Bat代码中,这给了我错误:重载的"Bat()"的调用是不明确的Bat(;)
- 不明确的错误重载运算符<<QdataStream 子类和个人类
- 具有相同参数的不同模板模板参数的错误重载函数
- 编译错误:重载函数的多个实例与 arument 列表匹配
- clang-libc++错误:重载解析选择了隐式删除的复制赋值运算符
- 错误:重载的调用不明确
- C++ 编译器选择输出流运算符<<的错误重载
- 分段错误重载运算符<<
- 错误:重载函数的多个实例与参数列表匹配
- 错误:重载的“max(int, int)”的调用不明确
- C++编译器选择类成员函数的错误重载
- 编译错误:重载操作符()
- 错误:重载的“bind(int(Class::*)(int,int),Class*,int,int”的调用不明确
- 未解析的外部符号错误重载操作符+模板
- 错误重载在构建"OpenSubdiv"时具有类似的转换