Check for C++ template value zero fails

Instantiating the body of a function template means instantiating everything it uses. How does the body of sumAllValues<0> look like? It's something like this:

template <>
constexpr unsigned int sumAllValues<0>()
{
    static_assert (0 >= 0, "Value is less than zero!");
    return Value == 0 ? 0 : 0 + sumAllValues<0 - 1>();
}

See the call to sumAllValues<-1>? While it's not going to be evaluated, it still appears there and must therefore be instantiated. But Value is unsigned, so you get wrap around. (unsigned)-1 is a very large unsigned number, not something less than zero. So the recursion continues, and it may continue indefinitely if not for the implementation having its limits.

The version with the specialization doesn't have the same function body for sumAllValues<0>, so it never tries to instantiate sumAllValues<-1>. The recursion really stops at 0 there.

Prior to C++17, the specialization is probably the shortest way to get at the functionality you want. But with the addition of if constexpr, we can reduce the code to one function:

template <unsigned int Value>
constexpr unsigned int sumAllValues()
{
    if constexpr (Value > 0)
      return Value + sumAllValues<Value - 1>()

    return 0;
}

if constexpr will entirely discard the code in its branch if the condition isn't met. So for the 0 argument, there will not be a recursive call present in the body of the function at all, and so nothing will need to be instantiated further.


In addition to StoryTeller's answer:

An interesting detail on how if constexpr works (inverting the condition for illustration):

if constexpr(Value == 0)
    return 0;

return Value + sumAllValues<Value - 1>();

While the code after the if won't be executed, it is still there and must be compiled, and you fall into the same error you had already. In contrast to:

if constexpr(Value == 0)
    return 0;
else
    return Value + sumAllValues<Value - 1>();

Now, as residing in the else branch to the constexpr if, it will again be entirely discarded if the condition does match and we are fine again...