C++ C++;11:正确的std::数组初始化?

C++ C++;11:正确的std::数组初始化?,c++,arrays,c++11,initialization,c++14,C++,Arrays,C++11,Initialization,C++14,如果我按如下方式初始化std::array,编译器会给出一个关于缺少大括号的警告 std::array<int, 4> a = {1, 2, 3, 4}; std::数组a={1,2,3,4}; 这解决了问题: std::array<int, 4> a = {{1, 2, 3, 4}}; std::数组a={{{1,2,3,4}; 这是警告消息: missing braces around initializer for 'std::array<int, 4

如果我按如下方式初始化std::array,编译器会给出一个关于缺少大括号的警告

std::array<int, 4> a = {1, 2, 3, 4};
std::数组a={1,2,3,4};
这解决了问题:

std::array<int, 4> a = {{1, 2, 3, 4}};
std::数组a={{{1,2,3,4};
这是警告消息:

missing braces around initializer for 'std::array<int, 4u>::value_type [4] {aka int [4]}' [-Wmissing-braces]
在'std::array::value_type[4]{aka int[4]}'[-Wmissing brates]的初始值设定项周围缺少大括号

这只是我的gcc版本中的一个bug,还是故意这么做的?如果是,原因是什么?

这是
std::array
的简单实现:

template<typename T, std::size_t N>
struct array {
    T __array_impl[N];
};
模板
结构数组{
T__数组_impl[N];
};
它是一个聚合结构,其唯一的数据成员是传统数组,因此内部
{}
用于初始化内部数组

大括号省略在聚合初始化的某些情况下是允许的(但通常不推荐),因此在这种情况下只能使用一个大括号。请参见此处:

根据。只有在省略
=
时,才需要双大括号

// construction uses aggregate initialization
std::array<int, 3> a1{ {1,2,3} };    // double-braces required
std::array<int, 3> a2 = {1, 2, 3}; // except after =
std::array<std::string, 2> a3 = { {std::string("a"), "b"} };
//构造使用聚合初始化
std::数组a1{{1,2,3}};//需要双支架
数组a2={1,2,3};//以后除外=
数组a3={{std::string(“a”),“b”};

CWG 1270之前的C++11中需要双大括号(修订后的C++11和C++14及更高版本中不需要):

//构造使用聚合初始化
std::数组a1{{1,2,3}};//CWG1270修订版之前的C++11中需要双大括号
//(修订后的C++11和C++14及更高版本中不需要)
数组a2={1,2,3};//以后再也不需要了=

C++17
std::array
类模板参数推断(CTAD)

这是现在允许我们省略模板类型,以便以下工作:

main.cpp

#include <array>

int main() {
    std::array a{1, 2, 3};
}
例如,如果我们改为设置
-std=c++14
,它将无法编译:

error: missing template arguments before ‘a’
另见:


在Ubuntu 18.04、GCC 7.5.0上测试。

std::array
是一个聚合。不过,我想他们将来可能会用一个集合来实现它。@chris你的确切意思是什么?好吧,你知道如何使用
struct S{int I;int j;}并使用
S={5,6}初始化它?这就是聚合初始化
std::array
包含一个内置数组,可以通过初始值设定项列表对其进行初始化,该列表就是内部集合。外部集合用于聚合初始化。@chris所以在我的例子中“{1,2,3,4}”只是一个std::initializer_list对象,它本身必须放在实际的初始化括号中?嗯,我不太确定在引入该类型后如何处理内置数组初始值设定项列表,但这就是它的要点,是的。一个用于类,另一个用于类内的数组。标准的所有版本都允许大括号省略。哈,愚蠢的GCC警告>>我不知道已经出现了这种情况。我有同样的问题(2016年至今),但我用以下语法修复了它:“std::array a[]={1,2,3,4};”所以我添加了方括号而不是嵌套的花括号。也许有人知道为什么这个变体对我有效?@Sam,这有不同的含义。您发布的语法是创建一个std::array数组(二维数组),而不是单个数组(一维)。@cyberpunk_uu只有在您的编译器实现了解除该限制的情况下才这样做。@Chubbi但是为什么它会给我一个警告“std::array a={1,2,3,4}”那么?@cyberpunk_uu这只是一个虚假的警告。@cyberpunk_u你可以用额外的括号来满足它。这并不是GCC唯一一个恼人的警告(曾经看到过
在“| |”
?”中的“&&&”周围加上括号),该警告意味着编译器编写者认为您可能不够聪明,无法正确使用该语言功能。
g++ -ggdb3 -O0 -std=c++17 -Wall -Wextra -pedantic -o main.out main.cpp
error: missing template arguments before ‘a’