C ++ 11使用非静态成员初始值设定项对类进行聚合初始化

标准允许吗?

struct A { int a = 3; int b = 3; }; A a{0,1}; // ??? 

这个类是聚合的吗? clang接受这个代码,但gcc不。

在具有类内成员初始值设定项的C ++ 11中,struct / class不是一个聚合 – 但是在C ++ 14中已经改变了。 当我第一次遇到这个问题的时候,我发现这是令人惊讶的,这个限制的基本原理是类内的初始化与用户定义的构造非常相似,但是相反的观点是没有人真的希望添加类内的初始化他们的类/结构非聚合,我当然没有。

从C ++ 11标准草稿 8.5.1节( 重点介绍 ):

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

在C ++ 14中 ,同一段落的内容如下:

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

N3605:成员初始值设定项和汇总项包含以下摘要:

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

这个评论基本上总结了不愿让他们成为一个整体:

聚集不能有用户定义的构造函数,而成员初始化符本质上是某种用户定义的构造函数(元素) (参见Core Defect 886)。 我并不反对这种扩展,但它也对我们的聚合模型实际上有什么影响。 接受这个扩展后, 我想知道如何教导什么是一个聚合。

修订版N3653于2013年5月通过。

更新

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

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

看到它现场直播 。