我正在为g++ 17编译C++ 17。
std::array<std::vector<int>, 2> v = {{ {1,2}, {3,4} }};我不明白为什么如果我删除数组的双大括号,它就不再工作了。
std::array<std::vector<int>, 2> v = { {1,2}, {3,4} }; // Does not compile我理解std::array的工作原理以及对双大括号的一般需求,但当我为C++17编译时,我希望能起到支撑作用。
为什么支撑在这里不适用?
发布于 2018-11-14 20:19:32
std::array<std::vector<int>, 2>有效
struct array {
std::vector<int> elems[2];
};elems是一个很好的子聚合。问题是,根据语言规则,如果初始化程序以{开头,则总是假定您没有省略大括号;相反,{1, 2}被视为整个子聚合elems的初始化器,试图用1初始化其第一个元素,用2初始化第二个元素(显然无效--不能将整数转换为vector --但不影响解释),而{3, 4}被认为是elems之后事物的初始化器--由于没有这样的事情,这是另一个错误。
用不是大括号的列表初始化第一个元素就足以触发大括号省略:
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-列表。
在这个领域,我们最好用代码来指定它。核心语言规则无视简单的语言规范,实现细节将会泄露--而且已经这样做了。
发布于 2018-11-14 17:52:09
正如T.C.指出的那样,我最初的解释不是corret,允许使用[dcl.init.aggr]p15
大括号可以在初始化程序列表中省略,如下所示。如果初始化程序-列表以左大括号开头,那么后续的逗号分隔的初始化程序-子句列表将初始化子聚合的元素;如果存在比元素更多的初始化项-子句是错误的。但是,如果子聚合的初始化程序-列表没有以左大括号开头,那么只需要从列表中获取足够多的初始化器-子句来初始化子聚合的元素;剩下的任何初始化-子句将用于初始化当前子聚合为元素的聚合的下一个元素。..。
但std::array根据array.overview
数组是一个聚合,可以使用最多N个元素初始化列表,其类型可转换为T。
我们的情况并非如此。
https://stackoverflow.com/questions/53305831
复制相似问题