Построить контейнер со списком инициализаторов итераторов

Можно построить вектор с диапазоном итераторов, например так:

std::vector<std::string> vec(std::istream_iterator<std::string>{std::cin},
std::istream_iterator<std::string>{});

Но я также могу скомпилировать и запустить код, используя унифицированный синтаксис C ++ 11 (обратите внимание на скобки), например так:

std::vector<std::string> vec{std::istream_iterator<std::string>{std::cin},
std::istream_iterator<std::string>{}};

Что на самом деле здесь происходит?

Я знаю, что конструктор принимает список инициализатора получает приоритет над другими формами строительства. Разве компилятор не должен разрешать конструктору брать список инициализаторов, содержащий 2 элемента std::istream_iterator? Это должно быть ошибкой как std::istream_iterator не может быть преобразовано в тип значения вектора std::string, право?

6

Решение

Из §13.3.2 / 1 ([over.match.list])

Когда объекты неагрегированного класса T инициализируются списком
(8.5.4), разрешение перегрузки выбирает конструктор в два этапа:

— Первоначально функции-кандидаты представляют собой список инициализаторов.
конструкторы (8.5.4) класса T и список аргументов состоит из
список инициализаторов как один аргумент.

— Если нет жизнеспособных
Найден конструктор списка инициализаторов, разрешение перегрузки
выполняется снова, где функции-кандидаты все
конструкторы класса T и список аргументов состоит из
элементы списка инициализатора.

В вашем случае конструктор списка инициализатора считается нежизнеспособным (потому что std::istream_iterator<std::string> не конвертируется в std::string), и второе условие применяется. В результате конструктор выбирает 2 итератора.

5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]