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

C++11 aggregate initialization for classes with non-static member initializers(具有非静态成员初始值设定项的类的 C++11 聚合初始化)
本文介绍了具有非静态成员初始值设定项的类的 C++11 聚合初始化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

标准中是否允许:

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).

An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no brace-or-equal initializers for non-static data members (9.2), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).

在 C++14 中,相同的段落读取:

and in C++14 the same paragraph reads:

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

An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).

此更改包含在 N3605:成员初始化器和聚合,其具有以下摘要:

This change is covered in N3605: Member initializers and aggregates which has the following abstract:

Bjarne Stroustrup 和 Richard Smith 提出了一个关于聚合的问题初始化和成员初始化器不能一起工作.这论文提议通过采用史密斯提议的措辞来解决这个问题消除了聚合不能有的限制成员初始值设定项.

Bjarne Stroustrup and Richard Smith raised an issue about aggregate initialization and member-initializers not working together. This paper proposes to fix the issue by adopting Smith's proposed wording that removes a restriction that aggregates can't have member-initializers.

这个评论基本上总结了不愿意让它们成为聚合体:

This comment basically sums up the reluctance to allowing them to be aggregates:

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

Aggregates cannot have user-defined constructors and member-initializers are essentially some kind of user-defined constructor (element) (see also Core Defect 886). I'm not against this extension, but it also has implications on what our model of aggregates actually is. After acceptance of this extension I would like to know how to teach what an aggregate is.

修订版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 聚合初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

相关文档推荐

Prevent class inheritance in C++(防止 C++ 中的类继承)
Why should I declare a virtual destructor for an abstract class in C++?(为什么要在 C++ 中为抽象类声明虚拟析构函数?)
Why is Default constructor called in virtual inheritance?(为什么在虚拟继承中调用默认构造函数?)
C++ cast to derived class(C++ 转换为派生类)
C++ virtual function return type(C++虚函数返回类型)
Is there any real risk to deriving from the C++ STL containers?(从 C++ STL 容器派生是否有任何真正的风险?)