我尝试包装一些类似于Qt的共享数据指针的东西来实现我的目的,经过测试,我发现当应该调用const函数时,却选择了它的非常量版本。
我正在使用C++0x选项进行编译,下面是一个最小的代码:
struct Data {
int x() const {
return 1;
}
};
template <class T>
struct container
{
container() {
ptr = new T();
}
T & operator*() {
puts("non const data ptr");
return *ptr;
}
T * operator->() {
puts("non const data ptr");
return ptr;
}
const T & operator*() const {
puts("const data ptr");
return *ptr;
}
const T * operator->() const {
puts("const data ptr");
return ptr;
}
T* ptr;
};
typedef container<Data> testType;
void testing() {
testType test;
test->x();
}
如您所见,Data.x是一个常量函数,因此调用的运算符->应该是常量函数。当我注释掉非常数时,它编译时没有错误,所以这是可能的。但是我的终端打印出来了:
“非常数数据收件人”
是不是一个GCC的bug (我的版本是4.5.2),或者是我遗漏了什么?
发布于 2011-09-03 01:26:00
如果您有两个仅在const
-ness方面不同的重载,那么编译器将根据*this
是否为const
来解析调用。在示例代码中,test
不是const
,因此调用非const
重载。
如果你这样做了:
testType test;
const testType &test2 = test;
test2->x();
您应该会看到调用了另一个重载,因为test2
是const
。
发布于 2011-09-03 01:28:52
test
是一个非常数对象,因此编译器会找到最佳匹配:非常数版本。不过,您可以使用static_cast
应用常量:static_cast<const testType&>(test)->x();
编辑:顺便说一句,因为你怀疑99.9%的时间你认为你发现了一个编译器错误,你应该重新检查你的代码,因为可能有一些奇怪的怪癖,而编译器实际上是遵循标准的。
发布于 2011-09-03 01:28:06
Data::x
是不是一个常量函数并不重要。被调用的运算符属于container<Data>
类而不是Data
类,并且它的实例不是常量,所以调用非常量运算符。如果只有常量运算符可用,或者类的实例本身是常量,那么就会调用常量运算符。
https://stackoverflow.com/questions/7287065
复制相似问题