5

底部的代码会生成以下编译时错误。std::vector<Node>如果我使用or ,错误就会消失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' 类型名称不完整 _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
};
4

4 回答 4

4

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

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

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

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

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

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

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

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

对于它的价值,同样的推理是启用 pimpl 成语的原因。

于 2014-12-30T06:46:04.770 回答
3

ANode显然不能包含三个Nodes
这将是一种递归关系,只能在以下两种情况之一下结束:

  1. 宇宙的尽头
  2. 她欺骗你

你的选择。IMO 都不是最优的。

于 2014-12-30T06:16:43.107 回答
1

您试图声明 Node 包含一个包含 3 个节点的成员。这根本不可能,因为它是无限递归。

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

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

于 2014-12-30T06:30:11.197 回答
0

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

于 2018-10-23T13:36:27.540 回答