15

这段代码:

class Foo {
    std::unordered_map<std::string, Foo> x;
};

给我一个错误:

/usr/include/c++/4.7/bits/stl_pair.h:94:11:
  error: 'std::pair<_T1, _T2>::second' has incomplete type
foo.cpp:4:7: error: forward declaration of 'class Foo'

但是,这段代码编译得很好:

class Foo {
    std::vector<Foo> x;
};

这是库/编译器错误吗?

4

1 回答 1

21

C++ 标准为各种智能指针指定模板参数允许为不完整类型。

标准的 2017 及更高版本value_type仅在为容器模板std::forward_liststd::list和实例化类模板时允许容器为不完整类型std::vector,并且仅当分配器类型满足“分配器完整性要求”时。默认分配器模板std::allocator始终满足分配器完整性要求。实例化容器类模板的任何成员仍然需要value_type完成。

对于任何其他标准容器类型,未提供此信息。在未指定的情况下,允许实现接受一个容器类模板而不是另一个容器类模板的不完整类型,并且仍然是一致的。

为了使您的代码可移植,请避免在类型完成之前制作任何类型的容器,除非标准特别允许。

形式上,一般约束可在适用于您的代码的以下规则 ( [res.on.functions] ) 中找到:

在某些情况下(替换函数、处理函数、用于实例化标准库模板组件的类型的操作),C++ 标准库依赖于 C++ 程序提供的组件。如果这些组件不满足其要求,则标准对实施没有要求。

特别是,在以下情况下效果是不确定的:

...

  • 如果在实例化模板组件时将不完整的类型用作模板参数,除非该组件特别允许。

在[forwardlist.overview] 、 [list.overview][ vector.overview ]部分中可以找到专门允许 、 和 的不完整模板参数的forward_list三个list语句。vector

于 2012-10-26T15:14:38.850 回答