The variable argument lists confuse the issue, because I think you're
misunderstanding partial specialization. I've failed to come up with
the standard reference, but basically, a partial specialization does a
pattern matching against the template arguments to use a different
definition - but the important thing is, any template argument list
supplied to the template must be valid for the primary template. The
specializations only come into play after that.
In other words, foo<int, float>, which seems what you want to write,
is not valid, because the foo template expects a non-type parameter of
type size_t in the first position. The partial specialization doesn't
Now, if your partial specialization is valid (I have no idea if it
is), this only means that if I write foo<1, int, float>, the primary
definition is chosen, whereas if I write foo<2, int, float>, pattern
matching resolves sizeof...(Types) to 2 and sees that the partial
specialization matches; this definition is chosen instead.