(This answer is based on @JohannesSchaub-litb's comments)
According to the standard, template parameter pack is not deducible if it is used in a function parameter pack not at the end of the parameter list.
§14.8.2.1/1 Deducing template arguments from a function call
[temp.deduct.call]:
When a function parameter pack appears in a non-deduced context
([temp.deduct.type]), the type of that parameter pack is never
deduced. [ Example:
template<class T1, class ... Types> void g1(Types ..., T1);
void h(int x, float& y) {
const int z = x;
g1(x, y, z); // error: Types is not deduced
g1<int, int, int>(x, y, z); // OK, no deduction occurs
}
— end example ]
And about non-deduced context, §14.8.2.5/5 Deducing template arguments from a type
[temp.deduct.type]:
A function parameter pack that does not occur at the end of the parameter-declaration-list.
So the direct reason of foo(1,1,1);
failed is that the template parameter Args
is not deduced, which is necessary to make the function invocation valid.
To explain the error message, a template parameter pack not deduced will be deduced to an empty sequence of template arguments[1], it means it'll be omitted. Then foo(1,1,1);
failed because the number of arguments doesn't match, that's what compiler complained.
Just as the example from standard shown, you could specify the template argument explicitly to avoid type deduction, even though it doesn't meet the original intent of your code. Such as:
template <typename T, typename... Args>
void foo(Args... args, T x) {
}
int main() {
// inside main()
foo<int, int, int>(1, 1, 1);
}
Here're some additional informations.
[1] I can't find direct expression about this in the standard. The most close one is this, "A trailing template parameter pack ([temp.variadic]) not otherwise deduced will be deduced to an empty sequence of template arguments."