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

jan*_*nde 7 c++ std stdvector language-lawyer c++11

出现以下问题:

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;
};
Run Code Online (Sandbox Code Playgroud)

这似乎违反直觉。如果std::vector需要完整的类型,则std::vector<parent>不应编译,因为在的类定义中仅知道其前向声明child

  • 这种行为在类定义方面有什么特别之处吗?
  • 我弄错std::vector了吗,不需要完整的类型?
  • 或者,这只是a幸吗?从技术上讲,这是不允许的,但是无论如何它适用于所有实现...

编辑

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

eer*_*ika 10

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

[根据功能]

1在某些情况下(替换函数,处理函数,用于实例化标准库模板组件的类型的操作),C ++标准库取决于C ++程序提供的组件。如果这些组件不满足其要求,则 本标准对实施没有任何要求

2特别在以下情况下效果不确定

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


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]

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]).

  • @jan.sende 这里未定义意味着不能保证代码可以编译;这与在运行时执行非法操作(例如除以零)的情况不同,其中代码必须编译并运行以执行不涉及该非法操作的所有执行。 (2认同)