以下来自指定初始化程序的cppref:
struct A { int x; int y; int z; };
A b{.x = 1, .z = 2}; // ok, b.y initialized to 0
默认情况下,所有基本类型都是默认初始化的,而不是 C++ 中的零初始化。
为什么指定的初始化器对数据成员进行零初始化?
以下来自指定初始化程序的cppref:
struct A { int x; int y; int z; };
A b{.x = 1, .z = 2}; // ok, b.y initialized to 0
默认情况下,所有基本类型都是默认初始化的,而不是 C++ 中的零初始化。
为什么指定的初始化器对数据成员进行零初始化?
对于非联合聚合,未提供指定初始化程序的元素的初始化方式与上述相同,当初始化程序子句的数量小于成员数时(提供默认成员初始化程序,否则为空列表初始化) :
struct A { string str; int n = 42; int m = -1; }; A{.m=21} // Initializes str with {}, which calls the default constructor // then initializes n with = 42 // then initializes m with = 21
根据标准,[dcl.init.aggr]/5:
对于非联合聚合,不是显式初始化元素的每个元素都按如下方式初始化:
(5.1) 如果元素具有默认成员初始化程序 ( [class.mem] ),则从该初始化程序初始化该元素。
(5.2) 否则,如果元素不是引用,则从空初始化列表 ( [dcl.init.list] ) 复制初始化该元素。
(5.3) 否则,程序是非良构的。
在列表初始化(如果是聚合的情况下是聚合初始化)中没有初始化程序(并且没有默认成员初始化程序)的子对象A
是值初始化的(在子对象的情况下是零初始化int
)。它们不是默认初始化的。
在指定初始化程序之前就是这种情况,并且在您使用指定初始化程序时仍然是这种情况。例子:
struct A { int x; int y; int z; };
A b0; // default i.e. no initialisation for x,y,z
A b1 {}; // x, y and z are value initialised
A b2 {1}; // y and z are value initialised
A b3 {.x = 1, .z = 2}; // y is value initialised
这同样适用于数组,尽管不幸的是在标准 C++ 中没有指定的初始化器:
int arr0[3]; // default i.e. no initialisation
int arr1[3] {}; // all are value initialised
int arr2[3] {42}; // all but first are value initialised