Pourquoi la taille n’est-elle pas un argument de modèle de std :: initializer_list?

std::initializer_list est construit par le compilateur à partir d’une liste d’initialisation entre accolades et la taille de cette liste doit être une constante de temps de compilation.

Alors pourquoi le comité a-t-il décidé d’omettre la taille des arguments du modèle? Cela empêche éventuellement certaines optimisations et rend certaines choses impossibles (initialiser std::array partir de std::initializer_list ).

L’un des avantages du système existant est que vous pouvez exporter des fonctions qui prennent une liste initializer_list partir d’une DLL. S’il était basé sur la taille, ils devraient être expédiés en tant que source.

Si initializer_list été défini comme étant std::initializer_list , toute fonction prenant un initializer_list , où type est un type concret, doit maintenant être une fonction modèle basée sur la taille de cette liste. Sinon, ils devraient exiger que les utilisateurs transmettent une liste d’ initializer_list d’un type et d’une taille spécifiques.

Les deux sont assez inacceptables. Tout le monde n’écrit pas tout son code sous forme de modèles.

Vous pouvez initialiser un std::array partir d’une liste initialisée ( {} avec des éléments au milieu). Mais ce n’est pas la même chose que std::intiializer_list . La classe array est un type d’agrégat. C’est une structure qui contient un seul élément, qui est un tableau public. Par conséquent, sur une implémentation conforme C ++ 11, ceci devrait comstackr:

 std::array myArray = {1, 3, 5}; 

Cependant, {1, 3, 5} n’est pas un object std::initializer_list ; c’est simplement une liste d’initialisation entrelacée, qui peut être utilisée pour initialiser les types appropriés.

Vous ne pouvez pas transmettre un object std::initializer_list au constructeur d’un aggegate (car les agrégats n’ont pas de constructeurs), mais vous pouvez utiliser une liste initialisée pour invoquer l’initialisation d’agrégats pour initialiser un std::array , comme vous le feriez pour toute structure contenant un tableau.

La différence entre un std::initializer_list et un braced-init-list est un peu comme la différence entre un int et le 0 littéral. Il n’est pas (généralement) légal de convertir implicitement un object int en un type de pointeur, mais il est légal de convertir implicitement un entier littéral 0 en un type de pointeur. La façon dont fonctionne braced-init-lists est la suivante:

 int i = 0; //Legal void *j = 0; //Legal void *k = i; //Not legal std::array myArray = {1, 3, 5}; //Legal std::initializer_list myInitList = {1, 3, 5}; //Legal std::array myArray = myInitList; //Not legal