繁体   English   中英

联盟成员的C ++生命周期

[英]C++ lifetime of union member

在当前版本的C ++标准草案中, [basic.life] / 1表示:

对象或引用的生命周期是对象或引用的运行时属性。 如果变量是默认初始化的,则称其具有空的初始化,并且如果它是类类型或其(可能是多维的)数组,则该类类型具有普通的默认构造函数。 类型T对象的生命周期始于:

  • 获得具有适当对齐和T型尺寸的存储,并且

  • 它的初始化(如果有的话)完成(包括空的初始化)([dcl.init]),

除了如果对象是一个联合成员或其子对象,它的生命周期才开始,如果该联合成员是联合中的初始化成员([dcl.init.aggr],[class.base.init]),或者如[class.union] [...]

从那一段我明白,一个工会成员开始其生命的唯一方式是:

  • 该成员“是联合中的初始化成员”(例如,如果它在mem-initializer引用),或者
  • [class.union]中提到的其他一些方法

但是,[class.union]中唯一指定联合成员如何开始其生命周期的规范段落是[class.union] / 5 (但它仅适用于特定类型,即non-classnon-array或具有未删除的trivial构造函数的class类型,或此类型的数组)。

下一段[class.union] / 6 (包含注释和示例,因此它不包含规范性文本)描述了一种通过使用placement new-expression (如new (&u.n) N;更改联合的活动成员的方法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; 开始了un的一生?

谢谢!

关于这一点的一个重要规则是:

[class.union] / 1

在联合中,如果非静态数据成员的名称指的是其生命周期已开始但尚未结束的对象([basic.life]),则该成员处于活动状态。 ...

就此规则而言,活动成员可以在成员对象开始其生命周期的任何时候更改。 规则[class.union] / 5还允许通过分配给有限类型集合的非活动成员来更改活动成员。 缺少单独的新放置规则并不允许更改成员。 如果它从成员的生命周期开始,则该成员是该联合的活动成员。

所以,[basic.life/1]表示成员的生命周期只有在[class.union]这样说1时才开始,而[class.union / 1]表示该成员只有在其生命周期开始时才有效2 这确实看起来像是一个捕获22。

我以最有意义的方式阅读规则的最佳尝试是解释该位置 - 新的开始于成员的生命周期,因此[class.union / 1]适用,因此“或如[class.union]中所述”适用,因此突出显示的例外不适用。 接下来我想说生命开始了 ,但那个逻辑是循环的。

非规范性的[class.union] / 6非常清楚地表明新的布局是允许的,但规范性规则是纠结的。 我会说措辞可以改进。


1 (或当联盟与该成员初始化时,我们正在考虑的情况并非如此)

2 (或根据[class.union] / 5分配后,我们正在考虑的情况并非如此)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM