为什么在C ++ 14中对数组的初始化仍然需要双花括号? [英] Why does initialization of array of pairs still need double braces in C++14?

查看:168
本文介绍了为什么在C ++ 14中对数组的初始化仍然需要双花括号?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用C ++ 14标准, std :: array 的初始化可以使用单个花括号(请参见 http://en.cppreference.com/w/cpp/container/array ):

With the C++14 standard, the initialization of an std::array can go with single braces (see http://en.cppreference.com/w/cpp/container/array):

但是,这对于 std :: pair std :: array 不起作用。

This, however, does not work for an std::array of std::pair.

为什么这些工作:

std::pair<int, int> p { 1, 2 };
std::array<int, 3> a {1, 2, 3};

但这是 not 起作用的吗:

std::array<std::pair<int, int>, 3> b {{1, 11}, {2, 22}, {3, 33}};

这又能正常工作吗?

std::array<std::pair<int, int>, 3> b {{{1, 11}, {2, 22}, {3, 33}}};

另外,为完成起见,一个好的旧数组的初始化确实可以使用单个花括号

Also, for completion, the initialization of a good old array does work with single braces

std::pair<int, int> c[3] {{1, 11}, {2, 22}, {3, 33}};


推荐答案

著名的最令人讨厌的解析。我怀疑这是怎么回事:

This appears to be a parsing ambuguity somewhat similar to the famous most vexing parse. I suspect what's going on is that:

如果您写

std::array<std::pair<int, int>, 3> b {{1, 11}, {2, 22}, {3, 33}};

编译器有两种解释语法的方式:

the compiler has two ways to interpret the syntax:


  1. 执行全括号初始化(这意味着最外面的括号指的是 std :: array 的聚合初始化,而第一个最里面的成员初始化 std :: array 的内部成员表示,这是一个真正的C数组)。这将无法编译,因为 std :: pair< int,int> 随后无法由 1 初始化(全部大括号用完)。 clang会给出一个编译器错误,确切表明:

  1. You perform a full-brace initialization (meaning the outermost brace refers to the aggregate initialization of the std::array, while the first innermost one initializes the internal member representation of std::array which is a real C-Array). This will fail to compile, as std::pair<int, int> subsequently cannot be initialized by 1 (all braces are used up). clang will give a compiler error indicating exactly that:

error: no viable conversion from 'int' to 'std::pair<int, int>'
 std::array<std::pair<int, int>, 3> a{{1, 11}, {2, 22}, {3, 33}};
                                          ^

请注意,如果没有内部成员聚合要初始化,此问题也可以解决,即

Note also this problem is resolved if there is no internal member aggregate to be initialized, i.e.

std::pair<int, int> b[3] = {{1, 11}, {2, 22}, {3, 33}};

会像汇总初始化一样编译。

will compile just fine as aggregate initialization.

(您的意思。)您执行大括号删除的初始化,因此,最里面的大括号用于单个对的集合初始化,而内部数组表示的大括号被删除。请注意,即使没有这种歧义,如 rustyx的答案中正确指出的那样,大括号省略规则也不会作为 std :: pair 没有聚合类型,因此该程序仍会格式错误。

(The way you meant it.) You perform a brace-elided initialization, the innermost braces therefore are for aggregate-initialization of the individual pairs, while the braces for the internal array representations are elided. Note that even if there wasn't this ambiguity, as correctly pointed out in rustyx's answer, the rules of brace elision do not apply as std::pair is no aggregate type so the program would still be ill-formed.

编译器将首选选项1。通过提供额外的花括号,您可以执行全括号初始化并消除语法上的歧义。

The compiler will prefer option 1. By providing the extra braces, you perform the full-brace initialization and lift any syntactical ambiguity.

这篇关于为什么在C ++ 14中对数组的初始化仍然需要双花括号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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