C + + 11: 更正 std: : 数组初始化?

如果我像下面这样初始化一个 std: : 数组,编译器会给我一个关于缺少大括号的警告

std::array<int, 4> a = {1, 2, 3, 4};

这就解决了问题:

std::array<int, 4> a = {{1, 2, 3, 4}};

这是警告信息:

missing braces around initializer for 'std::array<int, 4u>::value_type [4] {aka int [4]}' [-Wmissing-braces]

这只是我的 gcc 版本中的一个 bug,还是有意为之? 如果是这样,原因是什么?

108347 次浏览

这是 std::array的基本实现:

template<typename T, std::size_t N>
struct array {
T __array_impl[N];
};

它是一个聚合结构,其唯一的数据成员是传统数组,因此内部 {}用于初始化内部数组。

大括号省略在某些情况下允许使用聚合初始化(但通常不推荐) ,因此在这种情况下只能使用一个大括号。看这里: 数组的 C + + 向量

根据 首选。只有在省略 =的情况下才需要双括号。

// 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"} };

CWG 1270之前的 C + + 11中需要双括号(在修订之后的 C + + 11和 C + + 14及以后的 C + + 11中不需要) :

// construction uses aggregate initialization
std::array<int, 3> a1{ {1, 2, 3} }; // double-braces required in C++11 prior to the CWG 1270 revision
// (not needed in C++11 after the revision and in C++14 and beyond)
std::array<int, 3> a2 = {1, 2, 3};  // never required after =

数组引用

C + + 17 std::array类模板参数演绎(CTAD)

这个 新的 C + + 17特性由标准库使用,现在允许我们省略模板类型,以便以下工作:

Main.cpp

#include <array>


int main() {
std::array a{1, 2, 3};
}

而不是 std::array<int, 3> a{1, 2, 3};

用以测试:

g++ -ggdb3 -O0 -std=c++17 -Wall -Wextra -pedantic -o main.out main.cpp

例如,如果我们改为设置 -std=c++14,它就无法使用以下命令进行编译:

error: missing template arguments before ‘a’

参见: 推导数组大小?

在 Ubuntu 18.04,GCC 7.5.0上测试。

我认为你可以简单地使用以下方法,

std::array <int, 6> numbers {0};
numbers[3] = 1;
std::ranges::copy(numbers,  std::ostream_iterator<int>(std::cout, ','));
numbers = {0};
std::cout << "\n";
std::ranges::copy(numbers,  std::ostream_iterator<int>(std::cout, ','));