使用 std::array 创建树

Creating a tree using std::array

本文关键字:创建 array 使用 std      更新时间:2023-10-16

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

在 main.cpp:1:0 包含的文件中:/usr/include/c++/4.9/array:In 实例化 'struct std::array': main.cpp:9:23:
从这里需要/usr/include/c++/4.9/array:97:56:错误: 'std::array<_Tp, _Nm>::_M_elems' 的类型不完整 键入名称 _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
};

如其他答案中所述,这里的基本问题是您在该类型的定义中使用了一个类型。

之所以存在此问题,是因为编译器必须知道类型有多大,以便将其作为数据成员。由于尚未完成 Node 类型的声明,因此编译器不知道它应该为类型 Node 的数据成员使用多少空间。

指针

之所以有效,是因为所有指针在内存中的大小都相同,变化的是它们指向的大小,只有在取消引用指针时才需要知道。

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

使用std::unique_ptr<Node>很好,原因与普通指针相同:指针的大小始终相同。

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

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

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

就其价值而言,同样的推理使痘痘成语成为可能。

一个Node显然不能包含三个Nodes
这将是一个递归关系,只能在以下两个条件之一下结束:

  1. 宇宙的终结
  2. 她欺骗你

您的选择。海事组织都不是最佳的。

您正在尝试声明节点包含拥有 3 个节点的成员。 这根本不可能,因为它是无限递归。

std::vector<节点>之所以有效,是因为向量最初是空的,并且是动态添加到的。

std::array<std::unique_ptr>, 3> 之所以有效,是因为这种类型的数组仅包含指向 Node 对象的指针,而不是对象本身。

就我而言,在数组声明中使用它之前,我只有类类型的声明。C++期待这个定义。