如何制作深常量指针 [英] How to make a deep-const pointer
问题描述
假设我想用 C++ 表示一棵二叉树.通常,我想要一个像这样的 Node
结构:
Let's say I want to represent a binary tree in C++. Usually, I want a Node
struct like this:
struct Node {
Node* left
Node* right;
};
(这里我使用结构体和原始指针只是为了简单起见.我知道我应该使用智能指针进行内存管理.)
(Here I use struct and raw pointers just for simplicity. I know I should use smart pointers for memory management.)
这种表示有一个问题:我永远不可能有一个深const
树.(如果可以,请纠正我.)我可以将单个 Node
标记为 const,但它的子项在 Node
中被硬编码为非 const
> 结构.
This representation has a problem: I can never have a deep-const
tree. (Correct me if I can.) I may mark a single Node
const, but its children is hard-coded as non-const
in the Node
struct.
(我可能会使用一些 template
hack 来制作 left
和 right
可选的 const
,但这使得const Node
和非const
Node
不兼容.)
(I may use some template
hack to make left
and right
optionally const
, but this makes the const Node
and non-const
Node
incompatible.)
很快我发现,如果我神奇地有一些深const
指针(比如deep_const_pointer
,这使得const
ness具有可传递性),我可以在 Node
中使用该指针,以便拥有 const
节点自动意味着拥有一个 const
子树.
Soon I found out, if I magically had some deep-const
pointer (say deep_const_pointer
, which makes const
ness transitive), I can use that pointer in Node
so that having a const
node automatically means having a const
sub-tree.
我尝试编写一个深const
指针类,结果如下:
I tried to write a deep-const
pointer class, and here is what I end up with:
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
ness 选择性地将其添加回来.但是,此实现允许以下内容:
Here I cast out the const
in the constructor and optionally add it back according to the const
ness of this pointer-like object. However, this implementation allows the following:
const int i = 42;
deep_const_pointer<int> p{&i};
*p = 0; // Oops!
所以这取决于用户是否正确标记指针是否为const
.
So it depends on the user to correctly mark whether the pointer is const
or not.
我应该如何构建一个深const
指针类?理想情况下,我希望 const
检查发生在编译时,并且该指针类占用与原始指针一样多的内存.(这排除了将 const
ness 保存到 bool
成员变量并检查每次访问的解决方案.)
How should I build a deep-const
pointer class? Ideally, I want the const
check happen at compile-time, and that pointer class takes as much memory as a raw pointer. (Which rules out the solution to save the const
ness to a bool
member variable and check on each access.)
EDIT:我检查了 std::experimental::propagate_const
,从我的角度来看,它确实不是deep-const"指针.我所说的深常量指针 P
的意思是:
EDIT: I checked std::experimental::propagate_const
, and it is indeed not a "deep-const" pointer from my perspective. What I meant by deep-const pointer P
is:
- 常量
P
是指向常量的指针; - 可变
P
是指向可变的指针; - 对非常量
P
的 const 引用被视为 constP
; - 由于指向常量的指针具有值语义,因此常量
P
应该可以轻松复制.
- Constant
P
is pointer-to-const; - Mutable
P
is pointer-to-mutable; - A const reference to a non-const
P
is treated as if it were a constP
; - Since pointer-to-const has value semantics, a const
P
should be trivially copyable.
propagate_const
不符合要求,因为:
- 它从不接受指向常量的指针;
- 不可复制(显式删除了复制构造函数);
从我收到的评论和回答来看,我猜这样的 P
在 C++ 中是无法实现的.
From the comments and answer I received, I guess such a P
is not implementable in C++.
推荐答案
编写一个可传递的-const
智能指针是一个已解决的问题,只需查找 std::experimental::propagate_const<>
.找到合适的实现应该不会太难.
Writing a transitive-const
smart pointer is a solved problem, just look up std::experimental::propagate_const<>
. It shouldn't be too hard to find appropriate implementations.
在您自己的尝试中,您从原始指针构造错误.您不应将 const
添加到指针对象类型,也不应使用强制转换将其去掉.
固定:
In your own try, you got constructing from a raw pointer wrong. You should not add const
to the pointee-type, nor strip it out with a cast.
Fixed:
explicit deep_const_pointer(T* p_)
: p{p_} {}
这篇关于如何制作深常量指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!