简体   繁体   English

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

[英]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的类定义中只有它的前向声明是已知的。

  • Is this behaviour something special about class definitions?这种行为对类定义有什么特别之处吗?
  • Did I get it wrong, and std::vector does not require a complete type?我弄错了吗, std::vector不需要完整的类型?
  • Or, is this just a fluke?或者,这只是侥幸? In that technically this isn't allowed, but it works for all implementations anyways...从技术上讲,这是不允许的,但无论如何它适用于所有实现......

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM