大多数时候,它将取决于容器实现细节(更准确地说,取决于在容器声明时实例化的内容和未实例化的内容)。显然,std::unordered_map
实现要求类型完整。与此同时,GCC 实施std::map
对于不完整的类型,编译得很好。
为了说明这种差异的根源,请考虑以下示例。假设我们决定自己进行简单的实现std::vector
-like 功能并声明我们的向量类如下
template <typename T> class my_vector {
T *begin;
T *end;
...
};
只要我们的类定义只包含指向T
, 方式T
类定义本身不需要完整。我们可以实例化my_vector
本身就是一个不完整的T
没有任何问题
class X;
my_vector<X> v; // OK
需要类型的“完整性”later,当我们开始使用(并因此实例化)各个方法时my_vector
.
但是,如果由于某种原因我们决定包含一个直接实例T
进入我们的向量类,事情将会改变
template <typename T>
class my_vector {
T *begin;
T *end;
T dummy_element;
...
};
现在的完整性T
在实例化时很早就需要my_vector
itself
class X;
my_vector<X> v; // ERROR, incomplete type
你的情况一定会发生类似的事情。的定义unordered_map
您正在处理的内容以某种方式包含一个直接实例A
。这就是为什么无法实例化的原因(显然,在这种情况下,您最终会得到无限递归类型)。
通过实施更好的思考unordered_map
将确保不包括A
作为直接成员。这样的实施不需要A
是完整的。正如您自己所指出的,Boost 的实现unordered_map
在这方面设计得比较好。