包含自身映射的C++ Struct

use*_*884 6 c++ syntax compiler-errors

简单的问题:我如何让它工作?

struct A {
    double whatever; 
    std::unordered_map<std::string, A> mapToMoreA; 
}
Run Code Online (Sandbox Code Playgroud)

g ++错误:std :: pair <_T1,_T2> :: second的类型不完整

据我所知,在实例化地图时,编译器需要知道A的大小,但它不知道这个,因为地图是在A的声明中声明的,所以这是解决这个问题的唯一方法来使用指针A(不喜欢这样做)?

AnT*_*AnT 5

大多数情况下,它将取决于容器实现细节(更准确地说,取决于在容器声明时实例化的内容和未实例化的内容)。显然,std::unordered_map实现需要类型是完整的。同时,GCC 的std::map编译实现与不完整的类型完全一致。

为了说明这种差异的来源,请考虑以下示例。假设我们决定对std::vector-like 功能进行我们自己的天真实现,并如下声明我们的向量类

template <typename T> class my_vector {
  T *begin;
  T *end;
  ...
};
Run Code Online (Sandbox Code Playgroud)

只要我们的类定义只包含指向 的指针TT就不需要类定义本身的类型是完整的。我们可以毫无问题地将my_vector自己实例化为不完整的T

class X;
my_vector<X> v; // OK
Run Code Online (Sandbox Code Playgroud)

稍后,当我们开始使用(并因此实例化) 的各个方法时,将需要类型的“完整性” my_vector

但是,如果出于某种原因我们决定将 的直接实例包含T到我们的向量类中,事情就会发生变化

template <typename T>
class my_vector {
  T *begin;
  T *end;
  T dummy_element;
  ...
};
Run Code Online (Sandbox Code Playgroud)

现在T,在其my_vector自身的实例化时,将需要非常早的完整性

class X;
my_vector<X> v; // ERROR, incomplete type
Run Code Online (Sandbox Code Playgroud)

在你的情况下肯定会发生这样的事情。unordered_map您正在处理的定义以某种方式包含A. 这就是无法实例化的原因(显然,在这种情况下,您最终会得到无限递归类型)。

通过实施更好的想法unordered_map将确保不A作为直接成员包含在自身中。这种实施不需要A是完整的。正如您自己指出的那样,Boost 的实现unordered_map在这方面设计得更好。