Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recursive calculation of variable template value

This is what I'm tying (and failing) to make work. The idea is that count<N> has to be equal to N. This is a simplified case of a more complex calculation, don't mind the apparent silliness of this code.

template <>
constexpr size_t count<0> = 0;

template <auto N>
constexpr size_t count = 1 + count<static_cast<size_t>(N) - 1>;

int main()
{
    return count<1>;
}

It doesn't compile:

<source>:5:23: error: expected initializer before '<' token

 constexpr size_t count<0> = 0;
                       ^

If I swap the general case with the specialization, it also doesn't compile. Is it even doable with variable templates?

Try it online

like image 748
Violet Giraffe Avatar asked Jan 02 '23 15:01

Violet Giraffe


1 Answers

Here's the correct version of the code:

template <auto N>
constexpr size_t count = 1 + count<static_cast<size_t>(N) - 1>;

template <>
constexpr size_t count<static_cast<size_t>(0)> = 0;

Observe the following:

  1. The primary template must be declared before any specializations. No exceptions.
  2. The specializations count<0> and count<static_cast<size_t>(0)> are different because their arguments have different types. In your original code, where you provide an explicit specialization count<0>, this specialization is not used by the recursion that occurs in count<1> as specified in your primary template definition, which is why the infinite recursion occurs.
like image 80
Brian Bi Avatar answered Jan 10 '23 06:01

Brian Bi