use*_*768 7 c++ initialization object-lifetime unions language-lawyer
在当前版本的C ++标准草案中,[basic.life] / 1 指出:
对象或引用的生存期是对象或引用的运行时属性。如果变量是默认初始化的,则被称为具有空虚的初始化;如果变量是类类型或其(可能是多维的)数组,则该类类型具有琐碎的默认构造函数。类型为T的对象的生存期始于以下情况:
获得具有适合T型的对齐方式和大小的存储,并且
它的初始化(如果有的话)已经完成(包括真空初始化)([dcl.init]),
除了对象是联合成员或其子对象的情况外,其生存期仅在该联合成员是联合中的初始化成员([dcl.init.aggr],[class.base.init])或按照[class.union]。[...]
从该段我知道,工会会员开始其存在的唯一途径是:
mem-initializer),或者然而,唯一的规范在[class.union]段落指定一个联合成员如何开始其生命周期是[class.union] / 5(但它仅适用于特定类型的,即,或者non-class,non-array或class类型与trivial构造是未删除或此类数组)。
下一个段落[class.union] / 6(包含一个注释和一个示例,因此不包含规范性文本)描述了一种通过使用placement new-expression,例如来更改联合的活动成员的方法new (&u.n) N;,其中
struct N { N() { /* non-trivial constructor */ } };
struct M { M() { /* non-trivial constructor */ } };
union
{
N n;
M m;
} u;
Run Code Online (Sandbox Code Playgroud)
我的问题是在标准中指定new (&u.n) N;从哪里开始的生命周期u.n?
谢谢!
关于这一点的一条重要规则是:
[类.联合]/1
在联合中,如果非静态数据成员的名称引用其生命周期已开始且尚未结束的对象 ([basic.life]),则该非静态数据成员处于活动状态。...
就这条规则而言,活动成员可以在成员对象开始其生命周期的任何时候发生变化。规则 [class.union]/5 还允许通过分配给有限类型集的非活动成员来更改活动成员。缺乏单独的放置新规则本身并不禁止更改成员。如果它开始成员的生命周期,则该成员是联盟的活跃成员。
因此, [basic.life/1] 表示仅当 [class.union] 如此表示时该成员的生命周期才开始1,并且 [class.union/1] 表示仅当其生命周期已开始时该成员才处于活动状态2。这看起来确实有点像第 22 条军规。
我以有意义的方式阅读规则的最佳尝试是解释 Placement-new 开始成员的生命周期,因此 [class.union/1] 适用,因此“或如 [class.union] 中所述”适用,因此突出显示的例外情况不适用。接下来我想说的是生命周期由此开始,但这个逻辑是循环的。
非规范的 [class.union]/6 非常清楚地表明 new 的放置是被允许的,但规范规则是混乱的。我想说的是,措辞还可以改进。
1(或者当联盟由该成员初始化时,这不是我们正在考虑的情况)
2(或按照 [class.union]/5 分配后,这不是我们正在考虑的情况)
| 归档时间: |
|
| 查看次数: |
196 次 |
| 最近记录: |