问题描述
标准中是否允许:
struct A
{
int a = 3;
int b = 3;
};
A a{0,1}; // ???
这个类还聚合吗?clang
接受此代码,但 gcc
不接受.
Is this class still aggregate?clang
accepts this code, but gcc
doesn't.
推荐答案
在 C++11 中,具有类内成员初始值设定项使结构/类不是聚合 —然而,这在 C++14 中有所改变.当我第一次遇到它时,我发现这是令人惊讶的,这种限制的基本原理是类内初始化器与用户定义的构造器非常相似,但反论点是没有人真正期望添加类内初始化器应该使他们的类/结构是非聚合的,我确定没有.
In C++11 having in-class member initializers makes the struct/class not an aggregate — this was changed in C++14, however. This is something I found surprising when I first ran into it, the rationale for this restriction is that in-class initializers are pretty similar to a user defined constructor but the counter argument is that no one really expects that adding in-class initializers should make their class/struct a non-aggregate, I sure did not.
来自 草案 C++11 部分 8.5.1
聚合(强调我的未来):
From the draft C++11 standard section 8.5.1
Aggregates (emphasis mine going forward):
聚合是没有用户提供的数组或类(第 9 条)构造函数 (12.1),非静态没有大括号或相等的初始值设定项数据成员 (9.2),没有私有或受保护的非静态数据成员(第 11 条),没有基类(第 10 条),也没有虚函数(10.3).
在 C++14 中,相同的段落读取:
and in C++14 the same paragraph reads:
聚合是没有用户提供的数组或类(第 9 条)构造函数 (12.1),没有私有或受保护的非静态数据成员(第 11 条),没有基类(第 10 条),也没有虚函数(10.3).
此更改包含在 N3605:成员初始化器和聚合,其具有以下摘要:
This change is covered in N3605: Member initializers and aggregates which has the following abstract:
Bjarne Stroustrup 和 Richard Smith 提出了一个关于聚合的问题初始化和成员初始化器不能一起工作.这论文提议通过采用史密斯提议的措辞来解决这个问题消除了聚合不能有的限制成员初始值设定项.
这个评论基本上总结了不愿意让它们成为聚合体:
This comment basically sums up the reluctance to allowing them to be aggregates:
聚合不能有用户定义的构造函数和成员初始化器本质上是某种用户定义的构造函数(元素)(另见核心缺陷 886).我不反对这个扩展,但它也对我们的模型有影响聚合实际上是.接受此扩展后我会想知道如何教授聚合是什么.
修订版N36532013 年 5 月.
更新
emsr 指出 G++ 5.0 现在支持具有非静态数据的 C++14 聚合使用 std=c++1y
或 -std=c++14
的成员初始值设定项:
emsr points out that G++ 5.0 now supports C++14 aggregates with non-static data member initializers using either std=c++1y
or -std=c++14
:
struct A { int i, j = i; };
A a = { 42 }; // a.j is also 42
看到它直播.
这篇关于具有非静态成员初始值设定项的类的 C++11 聚合初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!