#include <initializer_list> требуется для использования списка инициализатора в зависимости от диапазона для? - PullRequest
11 голосов
/ 18 января 2012

Окончательный стандарт C ++ 11 включает положения, основанные на диапазоне, чтобы «просто работать» для собственных массивов без необходимости включать <iterator> или любой другой заголовок. Это было решено в первую очередь, насколько я могу судить, в рабочем документе n2900 в результате комментариев UK 78 и 79.

Это предложение также включало в себя положение о неявно #include <initializer_list> в каждой единице перевода, так что, например, программа

#include <iostream>

int main()
{
    for (auto i : { 1, 2, 3, 4, 5 })
        std::cout << i << "\n";
}

будет соответствовать стандарту даже без включения <initializer_list>.

Однако, когда концепты были удалены из C ++ 11, основанный на диапазоне for был пересмотрен, как видно из n2930 . В то время как положение для массивов «просто работает» остается, нет упоминания, что то же самое верно для списков инициализаторов; действительно, спецификация, что различные заголовки контейнеров стандартной библиотеки будут #include <initializer_list>, а окончательный текст 8.5.4.2 подразумевает для меня противоположность.

Насколько я могу судить, это довольно близко к окончательной формулировке по теме. Итак, является ли вышеприведенная программа правильно сформулированной в отношении окончательного стандарта или мне нужно #include <initializer_list> даже использовать ее для диапазона? Другими словами, означает ли использование списка инициализаторов в основе на основе диапазона «использование std::initializer_list - даже неявное использование, в котором тип не назван» в 8.5.4.2 FDIS?

Ответы [ 2 ]

7 голосов
/ 18 января 2012

Я бы сказал, да. Согласно §6.5.4 [stmt.ranged] / 1, заявление

for (auto i : { 1, 2, 3, 4, 5 })
    ...

эквивалентно

auto&& __range = { 1, 2, 3, 4, 5 };
...

и это означает, что используется initializer_list<int>, а заголовок <initializer_list> должен быть включен.

2 голосов
/ 16 июля 2018

GCC 7.1 выдает следующую ошибку, если <initializer_list> не включено:

error: deducing from brace-enclosed initializer list requires #include <initializer_list>
     for (auto i : { 1, 2, 3, 4, 5 })
                                   ^

Чтобы увидеть эту ошибку, нужно пропустить <iostream>, потому что включение <iostream> также будет включать <initializer_list>.

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