为什么 std::vector 使用 class 定义中的不完整类型?

Why does std::vector work with incomplete types in class definitions?

提出以下问题:

c++ 标准似乎说,std::vector 需要一个完整的类型才能工作。 (参见 https://en.cppreference.com/w/cpp/container/vector )那么,为什么下面的代码仍然可以编译?

#include <vector>

struct parent;

struct child
{
    std::vector<parent> parents; //parent is incomplete here!
};

struct parent
{
    std::vector<child> children;
};

这似乎违反直觉。如果 std::vector 需要一个完整的类型,那么 std::vector<parent> 应该不会编译,因为在 child.

的 class 定义中只有它的前向声明是已知的

编辑

c++11 和 c++17 之间似乎有区别。我想了解c++11版本。

标准说(草案 N3690;这是 post C++11,C++14 之前):

[res.on.functions]

1 In certain cases (replacement functions, handler functions, operations on types used to instantiate standard library template components), the C++standard library depends on components supplied by a C++program. If these components do not meet their requirements, the Standard places no requirements on the implementation.

2 In particular, the effects are undefined in the following cases:

— if an incomplete type (3.9) is used as a template argument when instantiating a template component, unless specifically allowed for that component.

鉴于标准没有要求,并且效果是未定义的(据我所知,这与未定义的行为相同),与 "not work" 的实例化没有任何期望期望它(看起来)"work".


自 C++17 起,要求放宽,std::vector 要求值类型完整,如果与适当的分配器(默认分配器)一起使用是合适的)。 (这种自由并不扩展到使用所有成员函数;它们有额外的要求)。

标准报价(当前草案):

[vector.overview]

An incomplete type T may be used when instantiating vector if the allocator meets the allocator completeness requirements. T shall be complete before any member of the resulting specialization of vector is referenced.

[allocator.requirements.completeness]

If X is an allocator class for type T, X additionally meets the allocator completeness requirements if, whether or not T is a complete type:

  • X is a complete type, and
  • all the member types of allocator_­traits other than value_­type are complete types.

[default.allocator]

All specializations of the default allocator meet the allocator completeness requirements ([allocator.requirements.completeness]).