如何制作深常量指针 [英] How to make a deep-const pointer

查看:74
本文介绍了如何制作深常量指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我想用 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 来制作 leftright 可选的 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,这使得constness具有可传递性),我可以在 Node 中使用该指针,以便拥有 const 节点自动意味着拥有一个 const 子树.

Soon I found out, if I magically had some deep-const pointer (say deep_const_pointer, which makes constness 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 去掉,并根据这个类似指针的对象的 constness 选择性地将其添加回来.但是,此实现允许以下内容:

Here I cast out the const in the constructor and optionally add it back according to the constness 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 检查发生在编译时,并且该指针类占用与原始指针一样多的内存.(这排除了将 constness 保存到 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 constness 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:

  1. 常量 P 是指向常量的指针;
  2. 可变 P 是指向可变的指针;
  3. 对非常量 P 的 const 引用被视为 const P;
  4. 由于指向常量的指针具有值语义,因此常量 P 应该可以轻松复制.
  1. Constant P is pointer-to-const;
  2. Mutable P is pointer-to-mutable;
  3. A const reference to a non-const P is treated as if it were a const P;
  4. Since pointer-to-const has value semantics, a const P should be trivially copyable.

propagate_const 不符合要求,因为:

  1. 它从不接受指向常量的指针;
  2. 不可复制(显式删除了复制构造函数);

从我收到的评论和回答来看,我猜这样的 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆