我正在使用g编译C 17.我有以下内容:
std::array<std::vector<int>,2> v = {{ {1,2},{3,4} }};
我不明白为什么如果我删除数组的双括号它不再工作.
std::array<std::vector<int>,2> v = { {1,4} }; // Does not compile
我理解std :: array是如何工作的以及一般双括号的需要,但是当我正在为C 17编译时,我期望支撑elision发挥作用.
为什么括号不适用于此?
解决方法
std :: array< std :: vector< int>,2>是有效的
struct array { std::vector<int> elems[2]; };
elems是一个小分类就好了.问题在于,根据语言规则,如果初始化程序以{始终假设您没有删除括号;相反,{1,2}被用作整个子聚合元素的初始化器,试图用1和第二个元素初始化它的第一个元素(这显然是无效的 – 你不能将整数转换为向量 – 但不是不会影响解释,4}被认为是元素之后的事物的初始化者 – 因为没有这样的事情,这是另一个错误.
使用不是braced-init-list的东西初始化第一个元素足以触发大括号省略:
std::array<std::vector<int>,2> v = { std::vector<int>{1,4} };
请注意,从规范角度来看,库不保证std :: array< T,N>的初始化.除了另一个std :: array< T,N>之外的任何东西或“最多N个元素,其类型可转换为T”的列表.这显然排除了braced-init-lists,因为它们没有类型,实际上也不允许“双括号”,因为这只是一个特殊情况,它具有一个braced-init-list单个元素.
这是一个我们可能最好用代码指定它的区域.核心语言规则无法用语言轻松规范,实现细节也会漏掉 – 而且已经这样做了.