假设我想用 C++ 表示二叉树。通常,我想要一个Node
像这样的结构:
struct Node {
Node* left
Node* right;
};
(这里我使用结构体和原始指针只是为了简单起见。我知道我应该使用智能指针进行内存管理。)
这种表述有一个问题:我永远无法拥有深度-const
树。 (如果可以的话请纠正我。)我可以标记一个Node
const,但它的孩子被硬编码为非const
in the Node
struct.
(我可能会使用一些template
破解制作left
and right
可选地const
,但这使得 constNode
和非const
Node
不相容。)
很快我发现,如果我神奇地拥有一些深刻的——const
指针(比如deep_const_pointer
,这使得const
ness 及物性),我可以使用该指针Node
以便有一个const
节点自动意味着有一个const
子树。
我试图写一篇有深度的文章const
指针类,这就是我最终得到的结果:
template <typename T>
class deep_const_pointer {
public:
explicit deep_const_pointer(const T* p_)
: p{const_cast<T*>(p_)} {}
const T& operator*() const { return *p; }
T& operator*() { return *p; }
const T* operator->() const { return p; }
T* operator->() { return p; }
// etc.
private:
T* p;
};
这里我抛出了const
在构造函数中,并可选择根据const
这个类似指针的对象的性质。但是,此实现允许执行以下操作:
const int i = 42;
deep_const_pointer<int> p{&i};
*p = 0; // Oops!
所以这取决于用户正确标记指针是否为const
or not.
我该如何建立一个深层次的const
指针类?理想情况下,我想要const
检查发生在编译时,并且该指针类占用与原始指针一样多的内存。 (这排除了保存的解决方案const
对一个bool
成员变量并检查每次访问。)
EDIT: 我检查了std::experimental::propagate_const
,从我的角度来看,它确实不是一个“深层常量”指针。我所说的深层常量指针是什么意思P
is:
- 持续的
P
是指向 const 的指针;
- Mutable
P
是指向可变的指针;
- 对非常量的 const 引用
P
被视为 constP
;
- 由于指向 const 的指针具有值语义,因此 const
P
应该是可以简单复制的。
propagate_const
不符合要求,因为:
- 它从不接受指向 const 的指针;
- 它是不可复制的(显式删除复制构造函数);
从我收到的评论和回答来看,我猜是这样的P
无法在 C++ 中实现。