使用std :: array创建树

Agr*_*hak 5 c++ arrays tree c++11 stdarray

底部的代码生成以下编译时错误.如果我使用std::vector<Node>或,错误消失了std::array<unique_ptr<Node>, 3>.有人可以解释一下这是什么意思吗?

在main.cpp中包含的文件中:1:0:
/usr/include/ c++ /4.9/ array:在'struct std :: array'的实例化中:main.cpp:9:23:从这里需要/ usr/include/c ++/4.9/array:97:56:错误:'std :: array <_Tp,_Nm> :: _ M_elems'具有不完整的类型typename _AT_Type :: _ Type _M_elems; ^ main.cpp:3:7:错误:'类节点'类节点的前向声明

#include <array>

class Node
{
public:
  Node(Node* parent, int x) : parent_(parent), x_(x) {}
  Node* parent_;
  int x_;
  std::array<Node, 3> children_; // ERROR
};
Run Code Online (Sandbox Code Playgroud)

Mar*_*ark 4

正如其他答案中所述,这里的根本问题是您在该类型的定义内使用该类型。

这是一个问题的原因是编译器必须知道类型有多大才能将其作为数据成员。因为您尚未完成Node类型声明,所以编译器不知道应该为 类型的数据成员使用多少空间Node

指针之所以有效,是因为所有指针在内存中的大小都相同,不同的是它们所指向的内容的大小,您只需要在取消引用指针时知道这一点。

因此,使用定义std::array<Node, 3>内部Node不起作用,因为std::array将其内存放在声明的同一位置(在函数中,该位置是堆栈,在对象中,该位置位于对象本身中)。为了弄清楚需要多少内存,它需要知道 a 的大小Node,这就是问题所在。

使用 astd::unique_ptr<Node>是可以的,其原因与普通指针相同:指针的大小始终相同。

出于同样的原因,使用 astd::vector<Node>很好(原则上,但在实践中不一定),但可能不太明显:您可以认为vector有 2 个数据成员、一个指向 s 数组的指针Node和一个大小。关键部分是指针。vector因为只有a 内存中的生命的“句柄”Node和数据分配在其他地方,所以这是一种非常好的存储方式。

考虑到语言的限制,表达意图的最佳方式可能是: std::array<std::unique_ptr<Node>, 3>

您仍然拥有固定数量的子级、自动内存管理,并且不再遇到不知道该数据成员的存储占用空间有多大的问题。

无论如何,同样的推理也使得 pimpl 习语成为可能。