C ++ 11:正确的std :: array初始化吗?


69

如果我按以下方式初始化std :: array,则编译器会向我发出有关括号丢失的警告

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版本中的错误,还是故意做的?如果是这样,为什么?


3
std::array是一个汇总。我认为他们将来可能会与一组设备一起使用。
克里斯,

@chris到底是什么意思?
拜占庭语

4
好吧,您知道如何拥有struct S {int i; int j;};并使用进行初始化S s = {5, 6};。那就是聚合初始化。std::array包含一个内置数组,该数组可以通过内部构造函数的初始化列表进行初始化。外部集用于聚合初始化。
克里斯,

@chris因此,在我的情况下,“ {1、2、3、4}”只是一个std :: initializer_list对象,它本身必须放置在实际的初始化括号内吗?
2013年

好吧,我不太确定引入该类型后如何处理内置数组初始化程序列表,但这就是要点,是的。一个用于类,另一个用于类内的数组。
克里斯,

Answers:


49

这是以下内容的简单实现std::array

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

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

在某些情况下,可以使用聚合初始化来进行花括号省略(但通常不建议这样做),因此在这种情况下只能使用一个花括号。参见此处:数组的C ++向量


该标准的所有版本都允许省略括号。
Cubbi 2013年

呵呵,愚蠢的GCC警告>。>我当时还不知道这种情况。
克里斯,

我遇到了同样的问题(到2016年为止),但是我使用以下语法解决了这个问题:'std :: array <int,4> a [] = {1,2,3,4};' 因此,我添加了方括号而不是嵌套的花括号。也许有人知道为什么这个变体对我有用?
山姆

5
@Sam具有不同的含义。您发布的语法是创建std :: arrays数组(二维数组),而不是单个数组(一维数组)。
Pubby

36

根据cppreference。仅在=省略时才需要双括号。

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

4
@cyberpunk_仅在编译器实施了DR#1270来解除该限制的情况下。
Cubbi 2013年

@Chubbi但是为什么它会警告我“ std :: array <int,4> a = {1,2,3,4}”?
拜占庭语

@cyberpunk_这只是一个虚假的警告。
Cubbi 2013年

4
@cyberpunk_您可以用多余的花括号来简单地满足它。这不是海湾合作委员会发出的唯一令人讨厌的警告(见过suggest parentheses around ‘&&’ within ‘||’吗?)
Cubbi 2013年

2
该警告表示编译器作者认为您可能不够聪明,无法正确使用该语言功能。
皮特·贝克尔

6

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

// 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 =

std :: array参考


2

C ++ 17std::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’

另请参见:推导std :: array大小?

在Ubuntu 18.04,GCC 7.5.0上进行了测试。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.