这两行来自cppreference
这两个语句有什么区别吗?我没有看出任何区别。
c++14之前
如果大括号初始化列表为空且T是一个带有默认构造函数的类类型,则进行值初始化。否则,如果T是一个聚合类型,则执行聚合初始化。
c++14之后
如果T是一个聚合类型,则执行聚合初始化。否则,如果大括号初始化列表为空且T是一个带有默认构造函数的类类型,则进行值初始化。
这两行来自cppreference
这两个语句有什么区别吗?我没有看出任何区别。
c++14之前
如果大括号初始化列表为空且T是一个带有默认构造函数的类类型,则进行值初始化。否则,如果T是一个聚合类型,则执行聚合初始化。
c++14之后
如果T是一个聚合类型,则执行聚合初始化。否则,如果大括号初始化列表为空且T是一个带有默认构造函数的类类型,则进行值初始化。
两者之间的区别在于当满足以下两个条件时会发生什么:如果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
struct X {const int x; };
)。 - T.C.X
的已删除默认构造函数是否是平凡的 - 我认为根据当时的定义它是平凡的。如果我正确地阅读了维基笔记,CWG1301更改了值初始化的定义以拒绝已删除的构造函数,并重新排序了项目符号以保持{}
的有效性。 - T.C.区别在于检查的顺序,因此聚合类型检查首先进行,然后才是其余部分。
@cigien
和@StoryTeller
的编辑。 - pvc