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

Bik*_*eev 33 c++ gcc aggregate-initialization c++11 c++14

是否允许标准:

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

A a{0,1}; // ???
Run Code Online (Sandbox Code Playgroud)

这个课程仍然是聚合的吗? clang接受此代码,但gcc不接受.

Sha*_*our 43

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

草案C++ 11标准部分8.5.1 聚合(强调我的未来):

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

C++ 14中,同一段落如下:

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

N3605中包含此更改:成员初始值设定项和聚合,具有以下摘要:

Bjarne Stroustrup和Richard Smith提出了一个关于聚合初始化和成员初始化器无法协同工作的问题.本文提出通过采用史密斯提出的措辞来解决这个问题,该措辞消除了聚合不能拥有成员初始化者的限制.

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

聚合不能有用户定义的构造函数, 成员初始化器本质上是某种用户定义的构造函数(元素)(另请参见核心缺陷886).我并不反对这种扩展,但它也会影响我们的聚合模型实际上是什么.在接受这个扩展之后,我想知道如何教授聚合是什么.

修订版N365320135月通过.

更新

emsr指出G ++ 5.0现在支持C++ 14聚合与非静态数据成员初始化器使用std=c++1y或者-std=c++14:

struct A { int i, j = i; };
A a = { 42 }; // a.j is also 42
Run Code Online (Sandbox Code Playgroud)

见它的工作现场.