在当前版本的C++标准草案中,[basic.life]/1状态:
The lifetime of an object or reference is a runtime property of the object or reference. A variable is said to have vacuous initialization if it is default-initialized and, if it is of class type or a (possibly multi-dimensional) array thereof, that class type has a trivial default constructor. The lifetime of an object of type T begins when:
storage with the proper alignment and size for type T is obtained, and
its initialization (if any) is complete (including vacuous initialization) ([dcl.init]),
except that if the object is a union member or subobject thereof, its lifetime only begins if that union member is the initialized member in the union ([dcl.init.aggr], [class.base.init]), or as described in [class.union]. [...]
从该段我了解到, union 成员开始其生命周期的唯一方式是:
- 该成员“是 union 中的初始化成员”(例如,如果它在
mem-initializer
中被引用),或者 - [class.union]中提到的一些其他方式
但是,[class.union] 中唯一的规范 段落指定了 union 成员如何开始其生命周期是 [class.union]/5 (但它仅适用于特定类型,即 non-class
、non-array
或具有 trivial< 的
未删除的构造函数,或此类类型的数组)。class
类型
下一段,[class.union]/6 (包含注释和示例,因此它不包含规范文本),描述了一种通过使用placement new-expression
来更改 union 的事件成员的方法,比如new (&u.n) N;
,其中
struct N { N() { /* non-trivial constructor */ } };
struct M { M() { /* non-trivial constructor */ } };
union
{
N n;
M m;
} u;
我的问题是,标准中的哪个地方规定了 new (&u.n) N;
开始 u.n
的生命周期?
谢谢!
最佳答案
关于此的重要规则是:
[class.union]/1
In a union, a non-static data member is active if its name refers to an object whose lifetime has begun and has not ended ([basic.life]). ...
就此规则而言,事件成员可以在成员对象开始其生命周期的任何时间更改。规则 [class.union]/5 还允许通过分配给一组有限类型的非事件成员来更改事件成员。缺少单独的新放置规则本身并不禁止更改成员。如果它开始于成员的生命周期,则该成员是联盟的活跃成员。
所以,[basic.life/1] 说成员的生命周期只有在 [class.union] 这么说1 时才开始,而 [class.union/1] 说成员仅当其生命周期开始时才处于事件状态2。这看起来确实有点像第 22 条军规。
我以一种有意义的方式阅读规则的最佳尝试是解释 placement-new 开始成员的生命周期,因此 [class.union/1] 适用,因此 “或如[class.union]" 适用,因此突出显示的异常(exception)不适用。接下来我想说生命因此开始,但这个逻辑是循环的。
非规范的 [class.union]/6 说得很清楚,放置 new 的目的是允许的,但是规范的规则很纠结。我会说措辞可以改进。
1(或者当 union 使用该成员初始化时,这不是我们正在考虑的情况)
2(或根据 [class.union]/5 分配后,我们正在考虑的情况并非如此)
关于 union 成员的 C++ 生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57877884/