Это плохо сформировано. Короче говоря, braced-init-list не может быть выведен при выводе аргумента шаблона, он рассматривается как невыгружаемый контекст .
6) Параметр P, чей A является списком фигурных скобок инициализации, но P не является std :: initializer_list или ссылкой на него:
Во-первых, автоматическое удержание типа использует правила вывода аргумента шаблона из вызова функции . [dcl.type.auto.deduct] / 4
(акцент мой)
Если заполнитель является автоматическим спецификатором типа, выводимый тип T '
замена T определяется с использованием правил для аргумента шаблона
вычет. Получить P из T, заменив вхождения auto на
либо новый параметр шаблона изобретенного типа U, либо, если
инициализация - копирование-список-инициализация, с
std::initializer_list<U>
. Выведите значение для U, используя правила
вывод аргумента шаблона из вызова функции, где P - это
Тип параметра шаблона функции и соответствующий аргумент - e.
Если вычет не удался, декларация неверна. [Пример:
const auto &i = expr;
Тип i - это выведенный тип параметра u в вызове f (expr) следующего изобретенного шаблона функции:
template <class U> void f(const U& u);
- конец примера]
Обратите внимание, что auto x({1, 2, 3, 4});
- это прямая инициализация, а не инициализация копирования, тогда параметр шаблона изобретенного типа - это просто U
, а не std::initializer_list<U>
, а соответствующий аргумент - {1, 2, 3, 4}
.
А в выводе аргумента шаблона из вызова функции , параметр шаблона не может быть выведен из списка braced-init-list. [temp.deduct.call] / 1
Вывод аргумента шаблона выполняется путем сравнения каждого типа параметра шаблона функции (назовите его P), который содержит параметры шаблона, которые участвуют в выводе аргумента шаблона, с типом соответствующего аргумента вызова (назовите его A), как описано ниже. Если удаление ссылок и cv-квалификаторов из P дает std :: initializer_list или P '[N] для некоторых P' и N, а аргумент является непустым списком инициализатора ([dcl.init.list]), то вычет вместо этого выполняется для каждого элемента списка инициализатора, принимая P 'в качестве типа параметра шаблона функции и элемент инициализатора в качестве аргумента, а в случае P' [N], если N является параметром шаблона нетипичного типа, N выводится из длины списка инициализатора. В противном случае аргумент списка инициализатора приводит к тому, что параметр считается неделедированным контекстом ([temp.deduct.type]). [Пример: * +1043 *
template<class T> void g(T);
g({1,2,3}); // error: no argument deduced for T
- конец примера]