指定的初始化和基类?

问题描述

在C ++ 20(最新草案)中,给出以下代码

struct B { int mb; };
struct D : B { int md; };

这六个表达式中哪些是格式错误的,哪些不是?

/*1*/ D{42,43}
/*2*/ D{{42},43}
/*3*/ D{42,.md = 43}
/*4*/ D{{42},.md = 43}
/*5*/ D{.mb = 42,.md = 43}
/*6*/ D{{.mb = 42},.md = 43}

解决方法

(2)是标准的显式聚合初始化。很好。

(1)是B子对象周围的带有括号的聚合初始化。也可以。

(3)和(4)将指定的初始值设定项与非指定的初始值设定项混合在一起,这是不允许的。 designated-initializer-list的语法只允许使用 designated-initializer-clause ,这是一个 designer . identifier 然后是括号或等号硝化器。没有其他形式。

(5)和(6)试图指定初始化基类子对象,这也是不允许的。所有指定者都必须命名直接的非静态数据成员。 [dcl.init.aggr]/3.1说:

如果初始化程序列表是 designated-initializer-list ,则聚合应为类类型,每个指定符中的标识符应命名类的直接非静态数据成员[。 ..]


proposal清楚地表明这两个都是预期的。它评论说:

基类对象将用{}初始化。对于如何初始化基类对象的深入控制,我们没有具体的用例,建议的设计是前向兼容的,因此我们建议在另一建议中解决此问题。

和:

全部指定者,或全部不指定。

有未来问题:

我们是否允许指定列表作为后缀出现在列表初始化器中,例如​A { 1,2,.c= 3,.d = 4 }​吗?