底部的代码会产生以下编译时错误。如果我使用 std::vector<Node>
,错误就会消失或 std::array<unique_ptr<Node>, 3>
.谁能解释一下这是怎么回事?
In file included from main.cpp:1:0: /usr/include/c++/4.9/array: In instantiation of ‘struct std::array’: main.cpp:9:23:
required from here /usr/include/c++/4.9/array:97:56: error: ‘std::array<_Tp, _Nm>::_M_elems’ has incomplete type typename _AT_Type::_Type _M_elems; ^ main.cpp:3:7: error: forward declaration of ‘class Node’ class Node
#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
类型的数据成员使用多少空间.
指针能工作的原因是因为所有指针在内存中的大小都相同,不同的是它们指向的内容的大小,您只需要知道何时取消引用指针。
因此,使用 std::array<Node, 3>
在你的 Node
里面定义不起作用,因为 std::array
将它的内存放在它被声明的地方(在函数中,那是堆栈,在对象中,那是在对象本身中)。要计算出需要多少内存,它需要知道 Node
的大小。 ,这就是问题所在。
使用 std::unique_ptr<Node>
出于与普通指针相同的原因,它很好:指针始终具有相同的大小。
使用 std::vector<Node>
出于同样的原因再次很好(原则上,但在实践中不一定),但也许不太明显:你可以想到 vector
有 2 个数据成员,一个指向 Node
数组的指针s 和尺寸。关键部分是指针。因为只有 vector
的“句柄”住在Node
里面的内存和数据分配在别处,这是一种非常好的存储方式。
鉴于语言的限制,表达您的意图的最佳方式可能是:
std::array<std::unique_ptr<Node>, 3>
您仍然有固定数量的 child ,自动内存管理,并且不再遇到不知道该数据成员的存储占用空间有多大的问题。
就其值(value)而言,同样的推理也是 pimpl 习语的成因。
关于c++ - 使用 std::array 创建树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27700492/