简体   繁体   English

c ++ 11聚合初始化之前的值初始化

[英]c++11 value-initialization prior to aggregate-initialization

I try to understand the first accepted answer of @bolov to the question Deleted default constructor. 我尝试将@bolov的第一个接受的答案理解为Deleted默认构造函数。 Objects can still be created... sometimes [1] 仍然可以创建对象...有时 [1]

It seems like I found a error there and so it messes up the whole explanation. 好像我发现了一个错误,所以它弄乱了整个解释。

@bolov explains why this code SUCCEED to be compiled in c++11: @bolov解释了为什么这个代码成功在c ++ 11中编译:

Scenario A 情景A.

struct foo {
  foo() = delete;
};

// All bellow OK (no errors, no warnings)
foo f = foo{};
foo f = {};
foo f{}; // will use only this from now on.

And why this code FAILS to be compiled in c++11: 为什么这个代码FAILS要用c ++ 11编译:

Scenario C 情景C.

struct foo {
  foo() = delete;
  foo(int) {};
};

foo f{}; // error call to deleted constructor

He says that the point is that the first one foo is an aggregate and the second one foo is not an aggregate. 他说重点是第一个foo是聚合,第二个foo不是聚合。

Then he gives the excerpt from cppreference: 然后他给出了cppreference的摘录:

The effects of list initialization of an object of type T are: ... 类型T对象的列表初始化的效果是:...

  • If T is an aggregate type, aggregate initialization is performed. 如果T是聚合类型,则执行聚合初始化。 This takes care of scenarios ABDE (and F in C++14) 这样可以解决ABDE(以及C ++ 14中的F)的情况
  • Otherwise the constructors of T are considered in two phases: 否则,T的构造函数分为两个阶段:

    • All constructors that take std::initializer_list ... 所有采用std :: initializer_list的构造函数......

    • otherwise [...] all constructors of T participate in overload resolution [...] This takes care of C (and F in C++11) ... 否则[...] T的所有构造函数都参与重载解析[...]这将照顾C(和C ++ 11中的F)......

According to the excerpt when you write foo f { }; 根据你写foo f {}时的摘录; in scenario A you get aggregate-initialization. 方案A中,您将获得聚合初始化。 An it would be great. 这会很棒。 But in reality in c++11 (#3337 draft, closest to standard) you have different initialization order : 但实际上在c ++ 11(#3337草案,最接近标准)中你有不同的初始化顺序

List-initialization of an object or reference of type T is defined as follows: 列表初始化对象或类型T的引用定义如下:

  • If the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized. 如果初始化列表没有元素且T是具有默认构造函数的类类型,则对象是值初始化的。
  • Otherwise, if T is an aggregate, aggregate initialization is performed (8.5.1) 否则,如果T是聚合,则执行聚合初始化(8.5.1)

So foo f { }; 所以foo f {}; in scenario A should result in value-initialization, that is, the DELETED default constructor will be called and the code should fail to be compiled. 方案A中应该导致值初始化,也就是说,将调用DELETED默认构造函数并且代码应该无法编译。

As a result of Core Issue 1301 , which was a defect against C++11, the precedence for list-initialization changed from: 作为Core Issue 1301的结果,这是针对C ++ 11的缺陷,列表初始化的优先级从以下变为:

List-initialization of an object or reference of type T is defined as follows: 列表初始化对象或类型T的引用定义如下:

  • If the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized. 如果初始化列表没有元素且T是具有默认构造函数的类类型,则对象是值初始化的。
  • Otherwise, if T is an aggregate, aggregate initialization is performed (8.5.1) 否则,如果T是聚合,则执行聚合初始化(8.5.1)

to: 至:

List-initialization of an object or reference of type T is defined as follows: 列表初始化对象或类型T的引用定义如下:

  • If T is an aggregate, aggregate initialization is performed (8.5.1) 如果T是聚合,则执行聚合初始化(8.5.1)
  • Otherwise, if the initialize list has no elements and T is a class type with a default constructor, the object is value-initialized. 否则,如果初始化列表没有元素且T是具有默认构造函数的类类型,则对象将进行值初始化。

So foo{} in Scenario A is still aggregate-initialization. 因此,场景A中的foo{}仍然是聚合初始化。

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

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