[英]Why does std::vector work with incomplete types in class definitions?
The following question came up:出现了以下问题:
The c++ standard seems to say, that std::vector
requires a complete type to work. C++ 标准似乎说,
std::vector
需要一个完整的类型才能工作。 (See https://en.cppreference.com/w/cpp/container/vector ) Then, why does the following code still compile? (参见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;
};
This seems counterintuitive.这似乎违反直觉。 If
std::vector
requires a complete type, then std::vector<parent>
should not compile because only its forward declaration is known inside the class definition of child
.如果
std::vector
需要完整类型,则std::vector<parent>
不应编译,因为在child
的类定义中只有它的前向声明是已知的。
std::vector
does not require a complete type?std::vector
不需要完整的类型? EDIT编辑
There seems to be a difference between c++11 and c++17. c++11 和 c++17 之间似乎有区别。 I would like to understand the c++11 version.
我想了解c++11版本。
Standard says (draft N3690; this is post C++11, pre C++14):标准说(草案 N3690;这是 C++11 之后,C++14 之前):
[res.on.functions]
[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.
1 在某些情况下(替换函数、处理函数、对用于实例化标准库模板组件的类型的操作),C++ 标准库依赖于由 C++ 程序提供的组件。 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:
2 特别是,在以下情况下的影响是不确定的:
— if an incomplete type (3.9) is used as a template argument when instantiating a template component, unless specifically allowed for that component.
— 如果在实例化模板组件时将不完整类型 (3.9) 用作模板参数,除非该组件特别允许。
Given that standard places no requirements, and effects are undefined (as far as I can tell, this is same as undefined behaviour), there is no expectation for the instantiation to "not work" any more than there is expectation for it to (appear to) "work".鉴于标准没有要求,并且效果未定义(据我所知,这与未定义的行为相同),没有期望实例化“不工作”比期望它(出现去工作”。
Since C++17, the requirement was relaxed and std::vector
does not require the value type to be complete, if used with appropriate allocator (the default allocator is appropriate).由于C ++ 17中,要求被放松和
std::vector
不需要值类型是完整的,如果与适当的分配器(默认分配器是合适的)中使用。 (This freedom does not extend to using all member functions; they have additional requirements). (这种自由不会扩展到使用所有成员函数;它们有额外的要求)。
Standard quote (current draft):标准报价(当前草案):
[vector.overview]
[vector.overview]
An incomplete type T may be used when instantiating vector if the allocator meets the allocator completeness requirements.
如果分配器满足分配器完整性要求,则在实例化向量时可以使用不完整类型 T。 T shall be complete before any member of the resulting specialization of vector is referenced.
在引用向量的结果特化的任何成员之前,T 应该是完整的。
[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 是类型 T 的分配器类,则 X 还满足分配器完整性要求,如果 T 是否为完整类型:
- X is a complete type, and
X 是完整类型,并且
- all the member types of allocator_traits other than value_type are complete types.
allocator_traits 的除 value_type 之外的所有成员类型都是完整类型。
[default.allocator]
[默认.分配器]
All specializations of the default allocator meet the allocator completeness requirements ([allocator.requirements.completeness]).
默认分配器的所有特化都满足分配器完整性要求([allocator.requirements.completeness])。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.