Fla*_*ire 4 c++ compiler-errors const reference c++11
我在我的代码中围绕一个对象创建了一个包装器,它应该修改对该对象的访问.我选择在这里使用一个对象进行测试,而不是一个具有相同功能的仿函数.基本上:包装器接收对对象的引用并转发对对象的所有索引访问(在一些可能的操作之后)
现在出现问题:访问器丢弃包装对象的常量.
最小的例子
struct Foo
{
std::array<int, 2> data;
const int& operator()(int idx) const{
return data[idx];
}
int& operator()(int idx){
return data[idx];
}
};
struct Bar
{
Foo& ref;
Bar(Foo& r):ref(r){}
int& operator()(int idx) const{
return ref(idx);
}
};
template< typename T >
void test(const T& data){
data(1) = 4;
std::cout << data(1);
}
void main(){
Foo f;
test(f);
// Above call does not compile (as expected)
// (assignment of read-only location)
Bar b(f);
test(b); // This does compile and works (data is modified)
}
Run Code Online (Sandbox Code Playgroud)
声明Bar(包装器)"const"的() - 操作符,我希望所有成员访问"const"到.所以不应该返回"int&"而只返回"const int&"
但是gcc4.7很高兴地编译代码并忽略const.这是正确的行为吗?这指定在哪里?
编辑:在相关问题上:如果在Foo中使用typedef,如:
struct Foo
{
using Ref = int&;
using ConstRef = const int&; //1
using ConstRef = const Ref; //2
int* data; // Use int* to have same issue as with refs
ConstRef operator()(int idx) const{
return data[idx]; // This is possible due to the same "bug" as with the ref in Bar
}
Ref operator()(int idx){
return data[idx];
}
};
Run Code Online (Sandbox Code Playgroud)
我注意到// 1确实按预期工作但// 2没有.返回值仍可修改.它们不应该是一样的吗?
是的,这是正确的行为.类型ref是Foo &.添加const到引用类型1没有任何作用 - 无论如何,引用已经是不可变的.这就像有一个成员int *p.在const成员函数中,其类型被视为int * const p,而不是int const * p.
您需要做的是const在const过载内手动添加,如果您需要它:
struct Bar
{
Foo& ref;
Bar(Foo& r):ref(r){}
int& operator()(int idx) const{
return const_cast<const Foo&>(ref)(idx);
}
};
Run Code Online (Sandbox Code Playgroud)
要解决编辑问题:不,typedef不一样.const int &是对(常量int)的引用.const Ref是常数Ref,也就是常数(参考int); 在数学意义上使用的括号.
1我在谈论参考类型本身.不要与添加const引用引用的类型相混淆.
| 归档时间: |
|
| 查看次数: |
135 次 |
| 最近记录: |