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
看到它现场直播 。