首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >std::array<std::vector>中的支撑省略

std::array<std::vector>中的支撑省略
EN

Stack Overflow用户
提问于 2018-11-14 17:32:56
回答 2查看 433关注 0票数 7

我正在为g++ 17编译C++ 17。

代码语言:javascript
复制
std::array<std::vector<int>, 2> v = {{ {1,2}, {3,4} }};

我不明白为什么如果我删除数组的双大括号,它就不再工作了。

代码语言:javascript
复制
std::array<std::vector<int>, 2> v = { {1,2}, {3,4} }; // Does not compile

我理解std::array的工作原理以及对双大括号的一般需求,但当我为C++17编译时,我希望能起到支撑作用。

为什么支撑在这里不适用?

EN

回答 2

Stack Overflow用户

发布于 2018-11-14 20:19:32

std::array<std::vector<int>, 2>有效

代码语言:javascript
复制
struct array {
    std::vector<int> elems[2];
};

elems是一个很好的子聚合。问题是,根据语言规则,如果初始化程序以{开头,则总是假定您没有省略大括号;相反,{1, 2}被视为整个子聚合elems的初始化器,试图用1初始化其第一个元素,用2初始化第二个元素(显然无效--不能将整数转换为vector --但不影响解释),而{3, 4}被认为是elems之后事物的初始化器--由于没有这样的事情,这是另一个错误。

用不是大括号的列表初始化第一个元素就足以触发大括号省略:

代码语言:javascript
复制
std::array<std::vector<int>, 2> v = { std::vector<int>{1,2}, {3,4} }; 

请注意,从规范的角度来看,该库并不保证std::array<T, N>的初始化来自其他std::array<T, N>或“最多可转换为T的N个元素”列表。这特别地排除了大括号-init-list_s,因为它们没有类型,而且实际上也不允许“双大括号”,因为这只是一个特殊的情况,即有一个单独的元素是一个支撑-init-列表。

在这个领域,我们最好用代码来指定它。核心语言规则无视简单的语言规范,实现细节将会泄露--而且已经这样做了。

票数 10
EN

Stack Overflow用户

发布于 2018-11-14 17:52:09

正如T.C.指出的那样,我最初的解释不是corret,允许使用[dcl.init.aggr]p15

大括号可以在初始化程序列表中省略,如下所示。如果初始化程序-列表以左大括号开头,那么后续的逗号分隔的初始化程序-子句列表将初始化子聚合的元素;如果存在比元素更多的初始化项-子句是错误的。但是,如果子聚合的初始化程序-列表没有以左大括号开头,那么只需要从列表中获取足够多的初始化器-子句来初始化子聚合的元素;剩下的任何初始化-子句将用于初始化当前子聚合为元素的聚合的下一个元素。..。

std::array根据array.overview

数组是一个聚合,可以使用最多N个元素初始化列表,其类型可转换为T。

我们的情况并非如此。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53305831

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档