如果绝对没有调用成员函数,是否允许使用不完整类型的向量?如果有,从什么时候开始?

Dan*_*our 5 c++ vector language-lawyer

假设我有一些不完整的类型

// in foo.hh
struct Hidden;
Run Code Online (Sandbox Code Playgroud)

我想用作 a 的元素类型std::vector。使用unionI 可以“推迟”对构造函数和析构函数的调用以std::vector实现联合构造函数/析构函数。

// in foo.hh
struct Public {
  union Defer {
    std::vector<Hidden> v;
    Defer();
    // add copy/move constructor if needed
    ~Defer();
  } d;
};
Run Code Online (Sandbox Code Playgroud)

现在我只能Public通过包含foo.hh和链接实现Public::Defer::Defer()和的文件来使用Public::Defer::~Defer()。只有那些需要访问Hidden.

这是合法的 C++ 吗?如果有,从什么时候开始?

背景:我在回答另一个问题时提出的问题

Igo*_*nik 4

在 C++14 之前,std::vector<T>使用不完整类型进行实例化是未定义的行为。T在 C++17 中,这个限制有所放松:

[vector.overview]/3如果分配器满足分配器完整性要求 17.6.3.5.1,则T实例化时可以使用不完整类型。应在引用所产生的专业化的任何成员之前完成。vectorTvector

(注意:默认分配器std::allocator确实满足这些完整性要求)。

我的理解是,对于 C++17,翻译单元包含标头(前向声明Hidden和定义 的标头Public)并定义变量是合法的Public pub;- 但实际上不使用pub.d.v. 在 C++17 之前,仅包含标头就已经触发未定义的行为。