具有非静态成员初始值的类的C ++ 11聚合初始化 [英] C++11 aggregate initialization for classes with non-static member initializers

查看:191
本文介绍了具有非静态成员初始值的类的C ++ 11聚合初始化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在标准中是允许的:

  struct A 
{
int a = 3;
int b = 3;
};

A a {0,1}; // ???

此类是否仍然聚合?
clang 接受此代码,但 gcc 不会。


<在C ++ 11中有类成员初始化器使得结构/类不是聚合—这在C ++ 14中改变了,但是。这是我发现令人惊讶的是,当我第一次遇到它,这个限制的基本原理是类的初始化器非常类似于用户定义的构造函数,但计数器的参数是没有人真正期望添加类的初始化器应该



草案C ++ 11标准部分 8.5.1 强调我的前进):


聚合是一个数组或类用户提供的
构造函数(12.1),非静态
数据成员
没有大括号或初始值设置(9.2),没有私有或受保护的非静态数据成员
(第11条),没有基类(第10条),没有虚函数
(10.3)。


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


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


此更改包含在 N3605:成员初始化和聚合 a>它有以下抽象:


Bjarne Stroustrup和Richard Smith提出了一个关于aggregate
初始化和成员初始化的问题一起工作。这个
文件建议通过采用Smith的建议措辞
来解决这个问题,它删除了聚合不能有
member-initializers
的限制。


此评论基本上总结了不允许它们成为聚合的意见:


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


N3653 的修订版本=http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/> 2013年5月。



更新



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

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

查看它工作直播


Is it allowed in standard:

struct A
{
  int a = 3;
  int b = 3;
};

A a{0,1}; // ???

Is this class still aggregate? clang accepts this code, but gcc doesn't.

解决方案

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.

From the draft C++11 standard section 8.5.1 Aggregates (emphasis mine going forward):

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

and in C++14 the same paragraph reads:

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

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

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:

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.

The revised version N3653 was adopted in May 2013.

Update

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

See it working live.

这篇关于具有非静态成员初始值的类的C ++ 11聚合初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆