具有非静态成员初始值设定项的类的C ++ 11聚合初始化

时间:2014-11-25 03:51:29

标签: c++ c++11 gcc c++14 aggregate-initialization

是否允许标准:

struct A
{
  int a = 3;
  int b = 3;
};

A a{0,1}; // ???

这个课程仍然聚合吗? clang接受此代码,但gcc没有。

1 个答案:

答案 0 :(得分:41)

在C ++ 11中,具有类内成员初始值设定项使得struct / class不是聚合 - 但是在C ++ 14中已经改变了。当我第一次遇到它时,我发现这是令人惊讶的,这个限制的基本原理是类内初始化器非常类似于用户定义的构造函数,但是计数器参数是没有人真正期望添加类内初始化器应该使他们的类/结构是非聚合的,我肯定没有。

来自draft C++11 standard部分8.5.1 聚合强调我的前进):

  

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

并在C++14同一段落中写道:

  

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

此更改包含在N3605: Member initializers and aggregates中,其中包含以下摘要:

  

Bjarne Stroustrup和Richard Smith提出了一个关于聚合的问题   初始化和成员初始化程序不能一起工作。这个   论文建议采用史密斯提出的措辞来解决问题   删除了聚合不能拥有的限制   构件-初始化

这个评论基本上总结了不允许它们成为聚合的方式:

  

聚合不能拥有用户定义的构造函数和   成员初始化程序本质上是某种用户定义的   构造函数(元素)(另请参阅核心缺陷886)。我并不反对这一点   扩展,但它也影响我们的模型   聚合实际上是。在接受此扩展后我愿意   想知道如何教授聚合物是什么。

N3653采用了修订版May 2013

更新

emsr使用std=c++1y-std=c++14指出G++ 5.0 now supports C++14 aggregates with non-static data member initializers

struct A { int i, j = i; };
A a = { 42 }; // a.j is also 42

看到它正常工作live