用删除的构造函数进行C ++ 14的值初始化

我有一些误解:

让我们把struct A的默认构造函数标记为已删除:

struct A { A() = delete; }; 

下一条指令是完整的,有什么作用?

 A a{}; 

从引用值的初始化

1)如果T是没有默认构造函数或用户提供的默认构造函数或删除了默认构造函数的类types,则该对象是默认初始化的。

但是默认初始化的效果是:

如果T是类types,则调用默认的构造函数来为新对象提供初始值。

或者它是聚合初始化? 谢谢!

你的struct A是:

  • 一个类的types有:
    • 没有用户提供的构造函数1
    • 没有私人或受保护的非静态数据成员,
    • 没有基类,
    • 没有虚拟成员function。

因此,根据§8.5.1 / 1的定义,它符合聚合types的要求

然后是聚合初始化优先于值初始化的优先级。 该标准指出,集合初始化优先于价值初始化(草案N3936,第8.5.4 / 3,第201页)(重点是我的)

Ttypes的对象或引用的列表初始化定义如下:

  • 如果T是聚合,则执行聚合初始化 (8.5.1)。
  • 否则,如果初始化程序列表中没有元素,并且T是具有默认构造函数的类types,则对该对象进行值初始化。
  • […更多规则…]

(1)根据评论中关于为什么一个被删除的构造函数不被视为用户定义的要求 ,这是标准说明的内容(草案N3936,§8.4.2/ 5,第198页):

一个函数是用户提供的,如果它是用户声明的,并且没有明确地默认或删除它的第一个声明。

它形成良好。 A是聚合1 ,根据草案N3936 ,在聚合的直接列表初始化中使用的空初始化列表会导致聚合初始化:

§8.5.4 / 3列表初始化[dcl.init.list]

Ttypes的对象或引用的列表初始化定义如下:

– 如果T是聚合,则执行聚合初始化(8.5.1)。

[例如:

struct S2 { int m1; double m2, m3; };

….

S2 s23{}; // OK: default to 0,0,0

….

– 结束示例]

….

C ++ 11和C ++ 1y之间的相关更改是对聚合情况下聚合与值初始化的优先级的更改:

C ++ 11带领

Ttypes的对象或引用的列表初始化定义如下:

– 如果初始化程序列表中没有元素,而T是具有默认构造函数的类types,则对该对象进行值初始化。

– 否则,如果T是聚合,则执行聚合初始化(8.5.1)….

接下来是上面的例子。

C ++ 1y优先考虑聚合初始化:

Ttypes的对象或引用的列表初始化定义如下:

– 如果T是聚合,则执行聚合初始化(8.5.1)。

….

– 否则,如果初始化器列表中没有元素,而T是具有默认构造器的类types,则对该对象进行值初始化。


1为什么是一个聚合?

这是一个在C ++ 11和C ++ 14中的聚合。

C ++ 1Y:

8.5.1聚合[dcl.init.aggr]

聚合是没有用户提供的构造函数(12.1),没有私有或受保护的非静态数据成员(第11章),没有基类(第10章),也没有虚函数(10.3)的数组或类)。

唯一不明显的部分是默认的构造函数是否是用户提供的。 它不是:

§8.4.2 [dcl.fct.def.default]中

一个函数是用户提供的,如果它是用户声明的,并且没有明确地默认或删除它的第一个声明。