为什么 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 定义中只有它的前向声明是已知的
- 此行为是否与 class 定义有关?
- 我是不是看错了,
std::vector
不需要完整类型?
- 或者,这只是侥幸?从技术上讲这是不允许的,但无论如何它适用于所有实现...
编辑
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]).
提出以下问题:
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 定义有关?
- 我是不是看错了,
std::vector
不需要完整类型? - 或者,这只是侥幸?从技术上讲这是不允许的,但无论如何它适用于所有实现...
编辑
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]).