c++ - 如何制作一个深const指针

标签 c++ pointers constants transitive-const

假设我想用C++表示一棵二叉树。通常,我想要这样的Node结构:

struct Node {
  Node* left
  Node* right;
};

(在这里我只是为了简单起见使用struct和raw指针。我知道我应该使用智能指针进行内存管理。)

这种表示形式有一个问题:我永远不会拥有一个深const树。 (如果可以,请更正我。)我可以标记一个Node const,但是其子级在const结构中被硬编码为非Node

(我可能会使用一些template hack来使leftright(可选)为const,但这会使const Node和非const Node不兼容。)

很快,我发现,如果我神奇地拥有一些深const指针(例如deep_const_pointer,这使const内在可传递),则可以在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

我应该如何建立一个Deep-const指针类?理想情况下,我希望const检查在编译时进行,并且该指针类占用的内存与原始指针一样多。 (这排除了将const ness保存到bool成员变量并检查每次访问的解决方案。)

编辑:我检查了std::experimental::propagate_const,从我的 Angular 来看,它的确不是“deep-const”指针。我的深度常量指针P的意思是:
  • 常量P是指向常量的指针;
  • 可变P是指向可变的指针;
  • 将对非const P的const引用视为是const P
  • 由于指向const的指针具有值语义,因此const P应该是可微复制的。
  • propagate_const无法满足要求,因为:
  • 它从不接受指向const的指针。
  • 不可复制(复制构造函数已明确删除);

  • 从我收到的评论和答案中,我猜想这样的P在C++中无法实现。

    最佳答案

    编写可传递const智能指针是一个已解决的问题,只需查找 std::experimental::propagate_const<> 即可。找到合适的实现应该不难。

    在您自己的尝试中,您从原始指针构造错误。您不应该将const添加到pointee类型,也不要使用强制转换将其删除。
    固定:

    explicit deep_const_pointer(T* p_)
        : p{p_} {}
    

    关于c++ - 如何制作一个深const指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61505046/

    相关文章:

    c++ - 用于保存对象的二维数组的变量

    c++ - Visual C++ - 读取文本文件,输出二维数组

    c++ - 新建 POD 的 c++ 对象(普通旧数据类型)

    c++ - const int *p 与 int const *p - 类型后的 const 是否可以接受?

    c++ 成员变量前面的括号

    c - 语句 *a[i]++/= K 有效吗?

    C - 使用指针查找最大值

    c++ - 为什么 C++ Builder 不能编译它?

    c++ - 在构造函数 C++ 标准中修改 const 吗?

    c++ - Clang-format 10.0 与 5.0 const 成员函数的格式不同