C ++ 11默认类成员初始化与初始化列表同时进行

时间:2017-08-23 08:52:14

标签: c++ c++11

有人可以指出我,对C ++标准的相应段落,或者可以提供一些解释,如果我取消注释文本({123}),为什么我的代码无法编译?

一般来说,我了解默认成员初始化和初始化列表初始化的使用有什么问题,但我无法提及确切的原因。

enum class MY: int
{
    A = 1
};

struct abc
{
    int a;/*{123};*/  //compilation failed if uncommented
    MY m;
};

abc a = {1, MY::A};

编译错误,如果是未注释的文本:

  

错误:无法将'<大括号括起来的清单列表>'中的'{1,A}'转换为'abc'

1 个答案:

答案 0 :(得分:5)

以下语法:

abc a = {1, MY::A};

是列表初始化,根据正在初始化的类型,它可以执行不同的操作。如果没有非静态数据成员初始值设定项(/*{123};*/),您的结构就是一个聚合,并且大小写在[dcl.init.list]/p3下:

  
      
  • 否则,如果T是聚合,则执行聚合初始化。
  •   

但是,要成为聚合类型,必须在C ++ 11中满足以下条件:

  

聚合是一个数组或类(第9条),没有用户提供的构造函数(12.1),没有用于非静态数据成员的大括号或等于初始化程序(9.2),没有私有或受保护的非静态数据成员(第11条),没有基类(第10条),也没有虚函数(10.3)。

也就是说,使用NSDMI(非静态数据成员初始化)会破坏上面的规则集,因此,不能再对列表初始化此类型的实例。

此规则在C ++ 14中已更改,当前的措辞显示为[dcl.init.aggr]/p1

  

聚合是一个数组或带有

的类      
      
  • (1.1)没有用户提供的,显式的或继承的构造函数([class.ctor]),

  •   
  • (1.2)没有私有或受保护的非静态数据成员([class.access]),

  •   
  • (1.3)没有虚函数,

  •   
  • (1.4)没有虚拟,私有或受保护的基类([class.mi])。

  •   
     

[注意:聚合初始化不允许访问受保护和私有基类'成员或构造者。 - 结束记录]