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