在std :: array初始化中的大括号 [英] Brace elision in std::array initialization

查看:620
本文介绍了在std :: array初始化中的大括号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设有一个 std :: array 要初始化。如果使用双括号可以:

  std :: array< int,2& x = {{0,1}}; 
std :: array< int,2> x {{0,1}};

在旧的聚合初始化中使用单个大括号也是可以的,因为大括号缺少的大括号:

  std :: array< int,2& x = {0,1}; 

但是,是否可以使用带单大括号的列表初始化? GCC接受它,Clang拒绝它当使用直接列表初始化时,不能省略括号初始化子对象。

  std: :array< int,2> x {0,1}; 

标准中提到的大括号的唯一部分是8.5.1 / 12,


在使用赋值表达式初始化聚合成员时,会考虑所有隐式类型转换(第4条)。如果赋值表达式可以初始化成员,则初始化该成员。否则,如果成员本身是一个子集合,假定大括号删除,并且考虑赋值表达式用于子集合的第一个成员的初始化。


8.5.1是专门关于聚合初始化的,所以这意味着Clang是正确的拒绝,对吧?不是很快。 8.5.4 / 3说:


类型T的对象或引用的列表初始化定义如下:



[...]



否则,如果T是一个聚合,则执行聚合初始化(8.5.1)。


我认为这意味着与聚合初始化完全相同的规则,包括大括号elision,适用,意味着GCC是正确的接受。 >

我承认,措辞并不是特别清楚。那么,哪个编译器正确的在处理第三个片段?

解决方案

大括号适用,但不适用于C + +11。在C ++ 14中,由于 http://www.open -std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1270 。如果你幸运的话,Clang会将它们退回到他们的C ++ 11模式(让我们希望他们会!)。


Suppose there's an std::array to be initialized. It's okay if using double braces:

std::array<int, 2> x = {{0, 1}};
std::array<int, 2> x{{0, 1}};

It's also okay to use single braces in the good old aggregate initialization, as the brace elision will take care of the missing braces:

std::array<int, 2> x = {0, 1};

However, is it okay to use list-initialization with single braces? GCC accepts it, Clang rejects it with "cannot omit braces around initialization of subobject when using direct list-initialization".

std::array<int, 2> x{0, 1};

The only part of the standard where brace elision is mentioned is 8.5.1/12, which says:

All implicit type conversions (Clause 4) are considered when initializing the aggregate member with an assignment-expression. If the assignment-expression can initialize a member, the member is initialized. Otherwise, if the member is itself a subaggregate, brace elision is assumed and the assignment-expression is considered for the initialization of the first member of the subaggregate.

8.5.1 is about aggregate initialization specifically, so that should mean Clang is correct to reject, right? Not so fast. 8.5.4/3 says:

List-initialization of an object or reference of type T is defined as follows:

[…]

— Otherwise, if T is an aggregate, aggregate initialization is performed (8.5.1).

I thinks it means that the exact same rules as with aggregate initialization, including brace elision, apply, meaning GCC is correct to accept.

I admit, the wording is not particularly clear. So, which compiler is right in its treatment of the third snippet? Does the brace elision happen in list-initialization, or it doesn't?

解决方案

Brace elision applies, but not in C++11. In C++14, they will apply because of http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1270 . If you are lucky, Clang will backport that to their C++11 mode (let's hope they will!).

这篇关于在std :: array初始化中的大括号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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