1

Using recursive templates, I would like to calculate the sum of the first n integers going from 0 to n. I.e. SumUp<10>::n would be 55. I wonder because I'm used to recursion going downwards (ie. from n to 0). Is it possible to go from 0 to n? Here's my attempt:

template<int n> struct SumUp {
    static constexpr int n = n;
};

template<> struct SumUp<0> {
    static constexpr int n = 0 + SumUp<n + 1>::n;  // <- Problem
};

The problem is, that in the second template, n is not known and therefore doesn't compile.

TMOTTM
  • 3,286
  • 6
  • 32
  • 63
  • How would a simple `SumUp<0>` work? You are still unconditionally calling `SumUp` – PaulMcKenzie Dec 09 '20 at 23:44
  • 1
    Is it possible, yes -- but like any recursive definition, you need to know the stopping point. If you want to count up, then you need to know what the end-point is (e.g. you need to pass `N` along with the start condition, and stop when `Current == N`) – Human-Compiler Dec 09 '20 at 23:53
  • Consider loop down: Sum<0> is 0, Sum is N + Sum. – 273K Dec 10 '20 at 00:19
  • Why not `std::integer_sequence` combined with a fold expression? – Shawn Dec 10 '20 at 04:09

1 Answers1

1

"Downwards" recursion counts upwards already.

When you do, for instance

int sum(int N)
{
    if (N == 0) return 0;
    return sum(N-1) + N
}

You actually compute sum(0) first.
Then sum(1) = sum(0) + 1
Then sum(2) = sum(1) + 2
Then sum(3) = sum(2) + 3

I wrote it as a regular function, but same holds regardless of language, be it runtime c++, templates, or visual basic.

Now if you want to reverse this and count downwards, you need to keep track of the target.

template<int N, int i = 0> struct SumUp {
    static constexpr int n = i + SumUp<N, i+1>::n;
};

template<int N> struct SumUp<N, N> {
    static constexpr int n = N;
};

static_assert(SumUp<1>::n == 1);
static_assert(SumUp<2>::n == 3);
static_assert(SumUp<3>::n == 6);
static_assert(SumUp<4>::n == 10);
  • First part defines SumUp<n, i> as the sum of integers in range [i..n].
  • Second part defines a stop condition when n == i.
spectras
  • 13,105
  • 2
  • 31
  • 53
  • Not sure what you mean. If it makes it clearer, you can do `SumUp { static constexpr int n = 0; }`. You would break the recursion one step later with the same result. Except I am not sure N, N+1 would work as a specialization. Perhaps with some integral_constat magic. – spectras Dec 10 '20 at 00:50
  • Oh right, it's late here my brain doesn't parse humour well so far in the night :) As for the point, I don't know, OP wanted to do it reversed, I guess as some training exercise or pure curiosity. – spectras Dec 10 '20 at 01:06
  • I think this is a simple solution that does what the OP requires. I did post an answer based on integer sequence, but I now think this is simpler. – jignatius Dec 11 '20 at 08:55