简体   繁体   English

聚合初始化与统一初始化

[英]Aggregate initialization vs uniform initialization

The more I read about C++11 uniform initialization, the more confused I am.我对 C++11 统一初始化的了解越多,我就越困惑。 Scott Meyers in Effective Modern C++ (page 55) says that the statement Scott Meyers 在 Effective Modern C++(第 55 页)中说声明

Widget w2{};

always calls the default constructor (even in the presence of constructor with a std::initializer_list argument).总是调用默认构造函数(即使存在带有std::initializer_list参数的构造函数)。

At first sight, this seems to be consistent with the 4th edition of Stroustrup book "C++ programing language", eg according to the table on page 1200 the statement乍一看,这似乎与第 4 版 Stroustrup 书“C++ 编程语言”一致,例如根据第 1200 页上的表格声明

std::atomic<T> x;

leaves the atomic variable uninitialized, while使原子变量未初始化,而

std::atomic<T> x {};

calls "default constructor" so that x represents a value initialized T object.调用“默认构造函数”,以便 x 表示一个已初始化的值 T object。

However, I can't believe that std::atomic<T> x;但是,我不敢相信std::atomic<T> x; does not call the default constructor in C++11 anymore, so I'm totally confused here.不再调用 C++11 中的默认构造函数,所以我在这里完全感到困惑。

Finally, after taking a look at C++11 standard (n3337 draft) my confusion is even bigger.最后,在查看了 C++11 标准(n3337 草案)之后,我的困惑就更大了。 On page 1102 we have:在第 1102 页,我们有:

template <> struct atomic<integral > {
  //[...] list of non-constructor functions
  atomic() noexcept = default;
  constexpr atomic(integral ) noexcept;
  atomic(const atomic&) = delete;
  //[...] other non-constructor functions
};

While on page 1104 (point 29.5.5) we see在第 1104 页(第 29.5.5 点)我们看到

The atomic integral specializations and the specialization atomic shall have standard layout.原子积分特化和特化原子应具有标准布局。 They shall each have a trivial default constructor and a trivial destructor.它们每个都应该有一个普通的默认构造函数和一个普通的析构函数。 They shall each support aggregate initialization syntax.它们都应支持聚合初始化语法。

So classes with user defined constructor now support aggregate initialization?那么具有用户定义构造函数的类现在支持聚合初始化吗? Is this so because the constuctor is constexpr ?这是因为构造函数是constexpr吗?

And what happens when we write当我们写作时会发生什么

std::atomic<T> x {};

Is this the aggregate initialization?这是聚合初始化吗? Or a call to the (trivial) default constructor?还是调用(微不足道的)默认构造函数?

So classes with user defined constructor now support aggregate initialization?那么具有用户定义构造函数的类现在支持聚合初始化吗?

Only aggregates support aggregate initialization.只有聚合支持聚合初始化。 An aggregate can have a user defined constructor only if the constructor is defined as defaulted or deleted.只有当构造函数被定义为默认或删除时,聚合才能具有用户定义的构造函数。

This will change in C++20 where no user declared constructors are allowed at all.这将在 C++20 中发生变化,其中根本不允许用户声明的构造函数。

Is this so because the constuctor is consexpr?这是因为构造函数是 consexpr 吗?

constexpr has no effect on this. constexpr对此没有影响。

 std::atomic<T> x {};

Is this the aggregate initialization?这是聚合初始化吗?

This is list initialization.这是列表初始化。 If the type is an aggregate, then list initialization would aggregate initialize the object.如果类型是聚合,则列表初始化将聚合初始化 object。 std::atomic is not an aggregate, because it has a user-provided constructor that is neither defaulted nor deleted: std::atomic不是聚合,因为它有一个用户提供的既不默认也不删除的构造函数:

 constexpr atomic( T desired ) noexcept; // (2) (since C++11)

For std::atomic , this rule of list initialization applies:对于std::atomic ,此列表初始化规则适用:

  • Otherwise, if the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized .否则,如果初始化列表没有元素并且 T 是具有默认构造函数的 class 类型,则 object 是value-initialized

And value initialization invokes the default constructor for such class.并且值初始化会调用此类 class 的默认构造函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM