Not sure but seems to me that g++ is right and clang++ is wrong.
songyuanyao is right saying that a template parameter isn't necessarily in last position when the "following parameters [...] have default arguments".
But g++ agree with this because if you add the default argument in the declaration, removing it from the definition,
template <typename ...Vs, typename = int>
void foo();
template <typename ...Vs, typename>
void foo() { }
int main ()
{
foo<char,float>();
}
both compilers (also g++) compile without problems.
So the point, IMHO, is: can we express template default arguments also in the function definition (function definition only; when preceded by a function declaration) or only in function declaration(s) ?
Isn't completely clear to me but, reading the C++17 standard, i see (17.1.9)
A default template-argument may be specified in a template declaration. A default template-argument shall not be specified in the template-parameter-list s of the definition of a member of a class template that appears outside of the member’s class. A default template-argument shall not be specified in a friend class template declaration. If a friend function template declaration specifies a default template-argument , that declaration shall be a definition and shall be the only declaration of the function template in the translation unit
So default template arguments are surely accepted in "declaration"s, not in "definition".
I repeat: not sure because is explicitly excluded in case of a definition of "a member of a class template that appears outside of the member’s class", not in case of a generic definition after a declaration.
Anyway, I don't see explicated that a default template argument can be accepted in a definition that is preceded by a declaration.
In 17.1.10 we have
The set of default template-argument s available for use is obtained by merging the default arguments from all prior declarations of the template in the same way default function arguments are
Again: "declarations", not "definition".
So I suppose that g++ is wrong because a default template-argument shouldn't be accepted in a definition after a declaration.