web-dev-qa-db-fra.com

Utiliser std :: array avec des listes d'initialisation

Sauf erreur, il devrait être possible de créer un tableau std: de la manière suivante:

std::array<std::string, 2> strings = { "a", "b" };
std::array<std::string, 2> strings({ "a", "b" });

Et pourtant, en utilisant GCC 4.6.1, je ne parviens pas à faire fonctionner ces éléments. Le compilateur dit simplement:

expected primary-expression before ',' token

et pourtant les listes d'initialisation fonctionnent très bien avec std :: vector. Alors c'est quoi? Suis-je dans l'erreur de penser que std :: array devrait accepter les listes d'initialisation, ou l'équipe de la bibliothèque standard C++ GNU a-t-elle raté?

54
Chris_F

std::array est drôle. Il est défini essentiellement comme ceci:

template<typename T, int size>
struct std::array
{
  T a[size];
};

C'est une structure qui contient un tableau. Il n'a pas de constructeur qui prend une liste d'initialisation. Mais std::array est un agrégat selon les règles de C++ 11, et peut donc être créé par initialisation d'agrégat. Pour agréger initialiser le tableau à l'intérieur la structure, vous avez besoin d'un deuxième ensemble d'accolades:

std::array<std::string, 2> strings = {{ "a", "b" }};

Notez que la norme suggère que les croisillons supplémentaires peuvent être élidés dans ce cas. Il s'agit donc probablement d'un bogue GCC.

86
Nicol Bolas

Pour ajouter à la réponse acceptée:

std::array<char, 2> a1{'a', 'b'};
std::array<char, 2> a2 = {'a', 'b'};
std::array<char, 2> a3{{'a', 'b'}};
std::array<char, 2> a4 = {{'a', 'b'}};

tous fonctionnent sur GCC 4.6.3 (Xubuntu 12.01). cependant,

void f(std::array<char, 2> a)
{
}

//f({'a', 'b'}); //doesn't compile
f({{'a', 'b'}});

ce qui précède nécessite des accolades doubles pour être compilé. La version avec accolades simples entraîne l'erreur suivante:

../src/main.cc: In function ‘int main(int, char**)’:
../src/main.cc:23:17: error: could not convert ‘{'a', 'b'}’ from ‘<brace-enclosed initializer list>’ to ‘std::array<char, 2ul>’

Je ne sais pas quel aspect de l'inférence/conversion de type fait fonctionner les choses de cette façon, ou s'il s'agit d'une bizarrerie de la mise en œuvre de GCC.

11
Joseph