列表初始化 - C++14 中发生了什么变化?

List initialization - What changed in C++14?

These two lines from cppreference

这两种说法有什么区别?我看不出有什么不同

until c++14

If the braced-init-list is empty and T is a class type with a default constructor, value-initialization is performed. Otherwise, if T is an aggregate type, aggregate initialization is performed.

since c++14

If T is an aggregate type, aggregate initialization is performed. Otherwise, if the braced-init-list is empty and T is a class type with a default constructor, value-initialization is performed.

区别在于检查的顺序,因此首先进行聚合类型检查,然后才是其余部分。

区别在于当两个条件都适用时会发生哪一个:如果 T 是聚合 class(与数组相反),它肯定有一个默认构造函数, and braced-init-list 为空。当然,要理解为什么这很重要,我们必须将值初始化与空列表的聚合初始化区分开来。

值初始化对对象进行零初始化,然后对其进行默认初始化,对于聚合来说,默认初始化它的每个成员,因此值初始化是针对成员的(加上零填充)。聚合初始化从 {} 初始化每个成员,这对许多类型来说也是值初始化,但对于 class 类型的成员,使用用户提供的默认构造函数是 默认初始化 .区别可见于

struct A {A() {} int i;};
struct B {A a;};  // aggregate
B b{};     // i is 0 in C++11, uninitialized in C++14
B b2=B();  // i is 0 in both versions

仅在 C++14 中,聚合可以具有默认成员初始化器;当然,这不会导致两种语言版本之间的行为差​​异,但无论如何它在这两个规则之间的行为并没有不同(因为它仅替换了常见的默认初始化)。