Code:
std::vector x{1,2,3,4}; std::array y{{1,2,3,4}};
Pourquoi ai-je besoin d’accolades doubles pour std :: array?
std::array
est un agrégat: il n’a pas de constructeur déclaré par l’utilisateur, pas même un constructeur prenant std::initializer_list
. L’initialisation à l’aide d’accolades est effectuée à l’aide de l’initialisation globale , une fonctionnalité de C ++ héritée de C.
L’ancien style de l’initialisation globale utilise le =
:
std::array y = { { 1, 2, 3, 4 } };
Avec cet ancien style d’initialisation des agrégats, les accolades supplémentaires peuvent être éliminées, ce qui équivaut à:
std::array y = { 1, 2, 3, 4 };
Toutefois, ces accolades supplémentaires ne peuvent être utilisées que “dans une déclaration de la forme T x = { a };
” (C ++ 11, §8.5.1 / 11), c’est-à-dire lorsque l’ancien style est utilisé. Cette règle autorisant l’élision des accolades ne s’applique pas à l’initialisation directe des listes. Une note de bas de page se lit comme suit: “Les accolades ne peuvent pas être éludées dans d’autres utilisations de l’initialisation des listes.”
Il y a un rapport de défaut concernant cette ressortingction: défaut du CWG # 1270 . Si la résolution proposée est adoptée, l’élision des accolades sera autorisée pour d’autres formes d’initialisation de liste, et les éléments suivants seront bien formés:
std::array y{ 1, 2, 3, 4 };
(Pointe du chapeau à Ville Voutilainen pour trouver le rapport de défaut.)
Parce que std::vector
propose un constructeur qui prend un std::initializer_list
, alors que std::array
n’a pas de constructeur et que la liste d’ std::initializer_list
{1, 2, 3, 4}
est en fait pas interprétée comme un std::initializer_list
, mais agrégation de l’initialisation pour le tableau interne de style C de std::array
(c’est là que provient le second ensemble: Un pour std::array
, un pour le std::array
interne des membres de style C).