首页 > 解决方案 > 列表初始化 - C++14 中发生了什么变化?

问题描述

在此处输入图像描述这两行来自cppreference

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

直到 c++14

如果花括号初始化列表为空且 T 是具有默认构造函数的类类型,则执行值初始化。否则,如果 T 是聚合类型,则执行聚合初始化。

从 c++14 开始

如果 T 是聚合类型,则执行聚合初始化。否则,如果括号初始化列表为空且 T 是具有默认构造函数的类类型,则执行值初始化。

标签: c++language-lawyerlist-initialization

解决方案


不同之处在于当两个条件都适用时会发生哪一个:如果T是一个聚合类(而不是一个数组),它肯定有一个默认构造函数,并且括号初始化列表为空。当然,要理解为什么这很重要,我们必须将值初始化与聚合初始化与空列表区分开来。

值初始化对对象进行零初始化,然后对其进行默认初始化,对于聚合而言,默认初始化其每个成员,因此值初始化是按成员进行的(加上零填充)。聚合初始化从 初始化每个成员{},这又是许多类型的值初始化,但对于具有用户提供的默认构造函数的类类型成员的默认初始化。可以看出区别

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 中,聚合可以有默认的成员初始化器;当然,这不会导致两种语言版本之间的行为差​​异,但是无论如何它在这两个规则之间的行为并没有不同(因为它只替换了常见的默认初始化)。


推荐阅读