You need a stopping state like the following:
template <>
int f2<0>()
{
return 0;
}
since f2<N - 1>()
has to be instantiated, you have your stopping state in your other case here:
template <> struct Factorial<0>
But if you are using constexpr
you don't really need to use templates at all since the whole point is that it will be done at compile time, so turn it into this:
constexpr int f2(int n)
{
return n == 0 ? 1 : (n * f2(n-1));
}