Let's say, I have the following piece of code:
#include <iostream>
template <size_t... Is> struct E {};
template <typename... Ts, size_t... Is>
void func (E<Is...>, Ts...) {std::cout << __PRETTY_FUNCTION__ << std::endl;}
int main()
{
func(E<1,2,3>{}, 1, 'a');
}
It works perfectly fine and produces
void func(E<Is ...>, Ts ...) [with Ts = {int, char}; long unsigned int ...Is = {1, 2, 3}]
However, if I replace func
call with func<int, char, 1, 2, 3>(E<1,2,3>{}, 1, 'a');
, it will cause the compilation error, i.e.,
template argument deduction/substitution failed
Why compiler forbids the explicit specification of multiple parameter packs?
This follows from the rules for template argument deduction.
When you explicitly specify the template parameters for func
, the compiler will match it to the first parameter pack greedily. The compiler does not figure out that once you start putting int
s in the parameters, it should start substituting for Is...
.
Instead, it will continue substituting for Ts...
, and you'll get an error message along the lines of:
expected a type, but got 1
for the 3rd explicitly specified parameter.
You can see this if you specify only the Ts...
, like this:
func<int, char>(E<1,2,3>{}, 1, 'a');
which compiles just fine.