Roman Kazmin
Roman Kazmin

Reputation: 981

Reqursive template function - howto

I'm beginner in the templates and I have one question. Is it possible to write recursive template function - for arithmetic progression for example? I'm trying to do the following:

template <typename T>
    T arithmetic_progression(T n)
    {
        return n + arithmetic_progression(n - 1);
    }
    
template <0> arithmetic_progression(T n) {
    return 0;
}

As result I receive compile error.

I know how to calculate in compile time using template of the struct - but really what I want - calculate it in runtime.

P.S. I don't want to use such variant:

template <typename T>
    T arithmetic_progression(T n)
    {
        if (n == 0) 
            return 0;
        else
            return n + arithmetic_progression(n - 1);
    }

Upvotes: 0

Views: 48

Answers (1)

MarkB
MarkB

Reputation: 1988

Given that you're a beginner, I'm going to assume you are open to use the following approach that allows for n being a known value at compile time.

Here is the compile time option. There is no way to do this at run-time.

#include <concepts>

template <std::integral T, T val>
constexpr T arithmetic_progression()
{
    static_assert(val >= 0, "must be non-negative");
    if constexpr (val == T{0})
        return T{0};
    else
        return val + arithmetic_progression<T, val-1>();
}

static_assert(arithmetic_progression<int, 0>() == 0);
static_assert(arithmetic_progression<int, 1>() == 1);
static_assert(arithmetic_progression<int, 2>() == 3);
static_assert(arithmetic_progression<int, 10>() == 55);
static_assert(arithmetic_progression<short, 10>() == 55);

Specifying the restriction of using a separate implementation for the base case is an unusual restriction. Nevertheless, it is possible to implement it in the way you request.

#include <concepts>

template <int val>
constexpr int arithmetic_progression()
{
    static_assert(val >= 0, "must be non-negative");
    return val + arithmetic_progression<val-1>();
}

template <>
constexpr int arithmetic_progression<0>() { return 0; }

static_assert(arithmetic_progression<0>() == 0);
static_assert(arithmetic_progression<1>() == 1);
static_assert(arithmetic_progression<2>() == 3);
static_assert(arithmetic_progression<10>() == 55);

P.S. There is a simple formula for arithmetic progression. The efficiency gained by computing this at compile time would be miniscule.

Upvotes: 1

Related Questions