I recently upgraded GCC to 8.2, and most of my SFINAE expressions have stopped working.
The following is somewhat simplified, but demonstrates the problem:
This is my take on it. In short, clang is right and gcc has a regression.
We have according to [temp.deduct]p7:
The substitution occurs in all types and expressions that are used in the function type and in template parameter declarations. [...]
This means that the substitution has to happen whether or not the pack is empty or not. Because we are still in the immediate context, this is SFINAE-able.
Next we have that a variadic parameter is indeed considered an actual template parameter; from [temp.variadic]p1
A template parameter pack is a template parameter that accepts zero or more template arguments.
and [temp.param]p2 says which non-type template parameters are allowed:
A non-type template-parameter shall have one of the following (optionally cv-qualified) types:
a type that is literal, has strong structural equality ([class.compare.default]), has no mutable or volatile subobjects, and in which if there is a defaulted member operator<=>, then it is declared public,
an lvalue reference type,
a type that contains a placeholder type ([dcl.spec.auto]), or
a placeholder for a deduced class type ([dcl.type.class.deduct]).
Note that void doesn't fit the bill, your code (as posted) is ill-formed.