假设我有一个像这样的简单类
class Foo
{
public:
void foo()const
{
str[5] = 'x';
obj->changeTheWorld();
x = 4;
y.get() = 5;
obj2->changeTheWorld();
}
private:
char *str; //some referenced data, not owned by Foo
ComplexObj *obj; //some referenced data, not owned by Foo
int &x; //references as well
//wrapped reference, but has a "T& get()const"
std::reference_wrapper<int> y;
//an occasionally useful pointer wrapper for complex memory cases
//but has a "T* get()const"
std::shared_ptr<ComplexObj> obj2;
};
这是有效的,因为在const方法中,它只是指针本身变为const,而不是它指向的数据。但是在许多情况下,这不是我想要的,如果const方法试图改变这些成员内容(直接或通过在该成员上调用非const方法),我想要编译错误。
是否有标准解决方案?
我认为某种包装类应该能够实现这一点,并且也应该是编译器优化的东西,尽管没有坐下来试图设计这样的东西来覆盖所有的情况,比如说{ {1}}和strong_const<char*> str
(也不确定一个好名字......)。
答案 0 :(得分:4)
嗯,std::reference_wrapper
和std::shared_ptr
都不提供常量传播,因此它们不比常规指针更“严格”。
我建议你制作自己的const传播类(我不确定 - 类似的东西已经由boost提供 - 请在评论中告诉我)
我的主张是这堂课:
#include <memory> // for pointer_traits
template <typename Pointer>
class ConstPropagatePointer
{
public:
using element_type = typename std::pointer_traits<Pointer>::element_type;
using pointer = typename std::pointer_traits<Pointer>::pointer;
using const_pointer = element_type const * const;
using reference = element_type&;
using const_reference = element_type const&;
ConstPropagatePointer(Pointer ptr) : ptr(ptr) {}
pointer operator -> ()
{
return &(*ptr);
}
const_pointer operator -> () const
{
return &(*ptr);
}
reference operator * ()
{
return *ptr;
}
const_reference operator * () const
{
return *ptr;
}
private:
Pointer ptr;
};
这样对你有用:
class Foo
{
public:
private:
ConstPropagatedPointer<char*> str;
ConstPropagatedPointer<ComplexObj*> obj;
ConstPropagatedPointer<std::shared_ptr<ComplexObj>> obj2;
};