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++ 吗?如果有,从什么时候开始?
背景:我在回答另一个问题时提出的问题。
在 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 之前,仅包含标头就已经触发未定义的行为。