假设有一个需要初始化的
在传统的聚合初始化中,使用单个大括号也可以,因为大括号省略会处理缺少的大括号:
然而,使用单花括号进行列表初始化是否可行?GCC可以接受,而Clang会拒绝,并显示“在使用直接列表初始化时,无法省略对子对象初始化周围的大括号”。
标准中提到花括号省略的唯一部分是8.5.1/12,其内容如下:
所有隐式类型转换(第4条款)在使用赋值表达式初始化聚合成员时都会被考虑。如果赋值表达式可以初始化一个成员,则该成员将被初始化。否则,如果该成员本身是子聚合,则假定省略了花括号,并且将考虑赋值表达式来初始化子聚合的第一个成员。
8.5.1特指聚合初始化,因此这意味着Clang的拒绝是正确的,对吗?不要太快下结论。8.5.4/3说:
对象或类型T的引用的列表初始化定义如下:
[...]
- 否则,如果T是聚合体,则执行聚合初始化(8.5.1)。
我认为这意味着与聚合初始化完全相同的规则,包括花括号省略,适用于列表初始化,这意味着GCC的接受是正确的。
我承认,措辞并不特别清晰。那么,在第三个片段的处理中,哪个编译器是正确的?花括号省略是否发生在列表初始化中?
std::array
。如果使用双括号,那么这是可以的:std::array<int, 2> x = {{0, 1}};
std::array<int, 2> x{{0, 1}};
在传统的聚合初始化中,使用单个大括号也可以,因为大括号省略会处理缺少的大括号:
std::array<int, 2> x = {0, 1};
然而,使用单花括号进行列表初始化是否可行?GCC可以接受,而Clang会拒绝,并显示“在使用直接列表初始化时,无法省略对子对象初始化周围的大括号”。
std::array<int, 2> x{0, 1};
标准中提到花括号省略的唯一部分是8.5.1/12,其内容如下:
所有隐式类型转换(第4条款)在使用赋值表达式初始化聚合成员时都会被考虑。如果赋值表达式可以初始化一个成员,则该成员将被初始化。否则,如果该成员本身是子聚合,则假定省略了花括号,并且将考虑赋值表达式来初始化子聚合的第一个成员。
8.5.1特指聚合初始化,因此这意味着Clang的拒绝是正确的,对吗?不要太快下结论。8.5.4/3说:
对象或类型T的引用的列表初始化定义如下:
[...]
- 否则,如果T是聚合体,则执行聚合初始化(8.5.1)。
我认为这意味着与聚合初始化完全相同的规则,包括花括号省略,适用于列表初始化,这意味着GCC的接受是正确的。
我承认,措辞并不特别清晰。那么,在第三个片段的处理中,哪个编译器是正确的?花括号省略是否发生在列表初始化中?