问题描述
在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 }
吗?