【发布时间】:2015-01-22 23:22:16
【问题描述】:
标准是否允许:
struct A
{
int a = 3;
int b = 3;
};
A a{0,1}; // ???
这个类仍然是聚合的吗?
clang 接受此代码,但 gcc 不接受。
【问题讨论】:
标签: c++ c++11 gcc c++14 aggregate-initialization
标准是否允许:
struct A
{
int a = 3;
int b = 3;
};
A a{0,1}; // ???
这个类仍然是聚合的吗?
clang 接受此代码,但 gcc 不接受。
【问题讨论】:
标签: c++ c++11 gcc c++14 aggregate-initialization
在 C++11 中,具有类内成员初始值设定项使结构/类不是聚合 - 然而,这在 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 提出了关于聚合的问题 初始化和成员初始化器不能一起工作。这 论文提议通过采用 Smith 提议的措辞来解决这个问题 消除了聚合不能具有的限制 成员初始化器。
这条评论基本上总结了不愿意让它们成为聚合体:
聚合不能有用户定义的构造函数和 成员初始化器本质上是某种用户定义的 构造函数(元素)(另请参见核心缺陷 886)。我不反对这个 扩展,但它也对我们的模型有影响 聚合实际上是。接受此扩展后我会 想知道如何教授聚合是什么。
更新
emsr 指出G++ 5.0 now supports C++14 aggregates with non-static data member initializers 使用std=c++1y 或-std=c++14:
struct A { int i, j = i; };
A a = { 42 }; // a.j is also 42
看到它在工作live。
【讨论】:
gcc?我无法使用-std=c++11 使用gcc 从4.7 复制到4.9。你能澄清你的问题吗,你说clang接受它,我猜你的意思是gcc?
-std=c+1y,它适用于clang,但不适用于gcc。我无法使用-std=c++11 在clang 中使用它,这是正确的。