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

标签 c++ c++11 aggregate language-lawyer value-initialization

我试图理解@bolov 对问题 Deleted default constructor. Objects can still be created... sometimes 的第一个接受的答案[1]

我好像在那里发现了一个错误,所以它搞砸了整个解释。

@bolov 解释了为什么这段代码在 c++11 中成功编译:

场景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.

为什么这段代码无法在 C++11 中编译:

场景 C

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

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

他说重点是第一个foo是聚合,第二个foo不是聚合。

然后他给出了 cppreference 的摘录:

The effects of list initialization of an object of type T are: ...

  • If T is an aggregate type, aggregate initialization is performed. This takes care of scenarios A B D E (and F in C++14)
  • Otherwise the constructors of T are considered in two phases:

    • All constructors that take std::initializer_list ...

    • otherwise [...] all constructors of T participate in overload resolution [...] This takes care of C (and F in C++11) ...

根据您在场景 A 中编写 foo f { }; 时的摘录,您将获得聚合初始化。那就太好了。但实际上在 c++11(#3337 草案,最接近标准)中你有不同的初始化顺序:

List-initialization of an object or reference of type T is defined as follows:

  • If the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized.
  • Otherwise, if T is an aggregate, aggregate initialization is performed (8.5.1)

所以 foo f { };场景 A 中应该会导致值初始化,也就是说,将调用 DELETED 默认构造函数并且代码应该失败编译。

最佳答案

由于 Core Issue 1301 ,这是针对 C++11 的缺陷,列表初始化的优先级从:

List-initialization of an object or reference of type T is defined as follows:

  • If the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized.
  • Otherwise, if T is an aggregate, aggregate initialization is performed (8.5.1)

到:

List-initialization of an object or reference of type T is defined as follows:

  • If T is an aggregate, aggregate initialization is performed (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.

所以场景 A 中的 foo{} 仍然是聚合初始化。

关于c++11 聚合初始化之前的值初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39588505/

相关文章:

Android 原生强指针与 std::shared_ptr

c++ - OpenGL 相机旋转不起作用

c++ - 为什么存在奇特的指针?

c++ - 在多文件项目中启动线程

c++ - 为什么我不能像这样淡化 std::array?

python - 如何对 pandas 中的索引和列进行分组

c++ - 如何将osgEarth的ViewerWidget放入选项卡式MdiArea中?

c++ - 有没有办法重载 << 以对某个类特化执行空操作?

c++ - 如何强制 pow(float, int) 返回 float

elasticsearch - Elasticsearch聚合是基于聚合还是多重聚合