为什么std :: vector可以在类定义中使用不完整的类型? [英] Why does std::vector work with incomplete types in class definitions?

查看:433
本文介绍了为什么std :: vector可以在类定义中使用不完整的类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

出现以下问题:

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

The c++ standard seems to say, that std::vector requires a complete type to work. (See https://en.cppreference.com/w/cpp/container/vector ) Then, why does the following code still compile?

#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的类定义中仅知道其前向声明.

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不需要完整的类型吗?
  • 或者,这只是a幸吗?从技术上讲,这是不允许的,但是无论如何它适用于所有实现...
  • Is this behaviour something special about class definitions?
  • Did I get it wrong, and std::vector does not require a complete type?
  • Or, is this just a fluke? In that technically this isn't allowed, but it works for all implementations anyways...

编辑

c ++ 11和c ++ 17之间似乎有所不同.我想了解c ++ 11版本.

There seems to be a difference between c++11 and c++17. I would like to understand the c++11 version.

推荐答案

标准说(草稿N3690;这是C ++ 11之后,C ++ 14之前的版本):

Standard says (draft N3690; this is post C++11, pre C++14):

[res.on.functions]

[res.on.functions]

1在某些情况下(替换功能,处理程序功能, 用于实例化标准库模板的类型的操作 组件),C ++标准库取决于 一个C ++程序.如果这些组件不符合要求, 该标准对实施没有任何要求.

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特别是在以下情况下,效果未定义:

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

-如果在以下情况下使用不完整的类型(3.9)作为模板参数 实例化模板组件,除非特别允许 该组件.

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

鉴于标准没有任何要求,并且效果是不确定的(据我所知,这与未定义的行为相同),对于实例化无效"的期望比对它的期望更高. (似乎)工作".

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".

从C ++ 17开始,放宽了要求,并且std::vector要求值类型完整(如果与适当的分配器一起使用(默认分配器是适当的)). (这种自由并不限于使用所有成员函数;它们还有其他要求).

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). (This freedom does not extend to using all member functions; they have additional requirements).

标准报价(当前草稿):

Standard quote (current draft):

[vector.overview]

[vector.overview]

如果分配器满足分配器完整性要求,则在实例化矢量时可以使用不完整类型T. 在引用所得的向量专业化的任何成员之前,T必须完整.

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]

[allocator.requirements.completeness]

如果X是类型T的分配器类,则无论T是否是完整类型,X都满足分配器完整性要求:

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是完整类型,并且
  • 除value_type以外的所有allocator_traits成员类型都是完整类型.

[default.allocator]

[default.allocator]

默认分配器的所有专业化都满足分配器完整性要求([allocator.requirements.completeness]).

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

这篇关于为什么std :: vector可以在类定义中使用不完整的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆