Pourquoi le comportement C ++ initializer_list pour std :: vector et std :: array est-il différent?

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).