您的报价确实涵盖了这一点:
如果初始值设定项是(无括号的)花括号初始化列表,则对象或引用是列表初始化的(8.5.4)。
跳到 8.5.4 列表初始化。在这里,我解释/省略了一些与以下情况无关的点T x{}
:
类型 T 的对象或引用的列表初始化定义如下:
- 如果 T 是聚合,则执行聚合初始化 (8.5.1)。
- 否则,如果初始值设定项列表没有元素并且 T 是具有默认构造函数的类类型,则该对象是值初始化的
- 否则,如果
T
是std::initializer_list<E>
[...]
- 否则,[如果列表不为空且与构造函数匹配]
- 否则,[如果列表只有一个元素]
- 否则,[如果
T
是引用类型]
- 否则,如果初始化列表没有元素,则对象被值初始化。
- 否则,程序格式错误。
第一点,聚合初始化也在 C++03 中;在那种情况下T x{};
是一样的T x = {};
。
对于第二点“T是具有默认构造函数的类类型”,它是值初始化的,这意味着调用默认构造函数。
如果T
是原始类型,则应用倒数第二个点并再次对其进行值初始化。
回到聚合初始化案例,在 8.5.1/7 中有:
如果列表中的初始化子句少于聚合中的成员,则每个未显式初始化的成员都应从其大括号或相等初始化器中初始化,或者,如果没有大括号或相等初始化器,从一个空的初始化列表(8.5.4)。
大括号或相等初始化器是指在类定义中内联提供的初始化器。如果它不存在,则它被初始化,就好像该成员已被初始化一样{}
(因此,此逻辑递归地应用于每个聚合成员)。
例如,
struct T
{
int a;
};
然后T x {};
导致a
被初始化为int a{};
,这是值初始化,因为int
它是原始类型。