Почему размер не является аргументом шаблона std :: initializer_list? - PullRequest
17 голосов
/ 18 августа 2011

std::initializer_list создается компилятором из заключенного в скобки списка инициализации, а размер этого списка должен быть постоянной времени компиляции.

Так почему же комитет решил опустить размер в аргументах шаблона? Это возможно предотвращает некоторые оптимизации и делает некоторые вещи невозможными (инициализация std::array из std::initializer_list).

Ответы [ 2 ]

14 голосов
/ 18 августа 2011

Если initializer_list был определен как std::initializer_list<type, size>, то любая функция, которая принимает initializer_list<type>, где type - это конкретный тип, теперь должна была бы быть функцией шаблона, основанной на этомразмер списка.Или они должны будут требовать, чтобы пользователи передавали initializer_list определенного типа и размера .

Оба из них довольно неприемлемы.Не все пишут весь свой код в виде шаблонов.

Вы можете инициализировать std::array из списка фигурных скобок ({} с содержимым посередине).Но это не то же самое, что std::intiializer_list.Класс array является агрегатным типом.Это структура, которая содержит один элемент, который является открытым массивом.Следовательно, в соответствующих реализациях C ++ 11 это должно скомпилировать:

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

Однако {1, 3, 5} не является std::initializer_list объектом;это просто фигурный список инициализации, который можно использовать для инициализации соответствующих типов.

Вы не можете передать объект std::initializer_list в конструктор aggegate (поскольку агрегаты не имеют конструкторов), но вы можетеиспользуйте инициализированный список с фигурными скобками для вызова инициализации агрегата для инициализации std::array, так же как и для любой структуры, содержащей массив.

Разница между std::initializer_list и фигурным списком инициализации:немного похоже на разницу между int и литералом 0.Неправильно (обычно) неявно преобразовывать объект int в тип указателя, но допустимо неявно преобразовывать целочисленный литерал 0 в тип указателя.Вот как работает braced-init-lists:

int i = 0;    //Legal
void *j = 0;  //Legal
void *k = i;  //Not legal

std::array<int, 3> myArray = {1, 3, 5};             //Legal
std::initializer_list<int> myInitList = {1, 3, 5};  //Legal
std::array<int, 3> myArray = myInitList;            //Not legal
7 голосов
/ 18 августа 2011

Одним из преимуществ существующей системы является то, что вы можете экспортировать функции, которые берут initializer_list из DLL.Если бы он был основан на размере, они должны были бы быть отправлены как источник.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...