Ответ 1
Он действителен для шаблонов функций, но только в том случае, когда вывод аргумента может помочь компилятору разрешить параметры шаблона, поскольку он соответствует вашему шаблону шаблона, практически бесполезен, потому что
template<typename T, typename... Args, typename S> void fn() { }
int main() { fn<int, int, int>(); }
test.cpp: In function 'int main()':
test.cpp:2:32: error: no matching function for call to 'fn()'
int main() { fn<int, int, int>(); }
^
test.cpp:1:57: note: candidate: template<class T, class ... Args, class S> void fn()
template<typename T, typename... Args, typename S> void fn() { }
^
test.cpp:1:57: note: template argument deduction/substitution failed:
test.cpp:2:32: note: couldn't deduce template parameter 'S'
int main() { fn<int, int, int>(); }
у компилятора нет способа определить, какие параметры шаблона относятся к пакету параметров, а к S
. Фактически, как @T.C. указывает, что на самом деле это должна быть синтаксическая ошибка, потому что шаблон функции, определенный таким образом, никогда не может быть создан.
Более полезный шаблон функции будет похож на
template<typename T, typename... Args, typename S> void fn(S s) { }
так как теперь компилятор может однозначно сопоставить параметр функции S
с типом шаблона S
, с побочным эффектом, который всегда будет выведен S
- все явные параметры шаблона после первого будут принадлежать Args
.
Ничего из этого не работает для шаблонов (первичных) классов, параметры не выводятся и явно запрещены:
Из черновика n4567
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4567.pdf
[temp.param]/11
[...] Если шаблон-шаблон шаблона первичного класса или псевдонима template является пакетом параметров шаблона, он должен быть последним шаблоны параметры. [...]
(если бы они были выведены, это было бы неоднозначно, как в примере шаблона функции).