Recursive variable templates

I tried to use variable templates in the same way as I use some other templates, for example: we already know how to calculate the Fibonacci number or number using metaprogramming with template objects wrapping a static value or an enumeration value .

So, the first thing I did was try to specialize the template variable, and it works as expected:

template <std::size_t VALUE> std::size_t value       = VALUE;
template <>                  std::size_t value<666u> = 1u;

std::cout << value<0u> << '\n';   // "0" as expected
std::cout << value<1u> << '\n';   // "1" as expected
std::cout << value<2u> << '\n';   // "2" as expected
std::cout << value<666u> << '\n'; // "1" as expected!!

Knowing that specialization of the variable template is possible, I tried to make the Fibonacci variable number:

template <std::size_t ITERATION>
std::size_t fibonacci = fibonacci<ITERATION - 1u> + fibonacci<ITERATION - 2u>;
template <> std::size_t fibonacci<1u> = 1u;
template <> std::size_t fibonacci<0u> = 0u;

int main()
{
    std::cout << fibonacci<5> << '\n'; // "8" expected;
    return 0;
}

Error received from Wandbox :

error: expected primary-expression before ';' token
template <std::size_t ITERATION> std::size_t fibonacci = fibonacci<ITERATION - 1u> + fibonacci<ITERATION - 2u>;
                                                                                                              ^

, , . , , , , , .

?

.

+4
1

, . , clang 3.7.0 , ( : fibonacci<0u> = 1u) 0 8 fibonacci<5>.

,

std::cout << fibonacci<0> << '\n'; // "1" expected;
std::cout << fibonacci<1> << '\n'; // "1" expected;
std::cout << fibonacci<2> << '\n'; // "2" expected;
std::cout << fibonacci<3> << '\n'; // "3" expected;
std::cout << fibonacci<4> << '\n'; // "5" expected;
std::cout << fibonacci<5> << '\n'; // "8" expected;

. Weird!

. , , :

template <std::size_t ITERATION>
constexpr std::size_t get_fibonacci()
{
    return get_fibonacci<ITERATION - 1u>() + get_fibonacci<ITERATION - 2u>();
}

template <>
constexpr std::size_t get_fibonacci<0u>() {
    return 1u;
}

template <>
constexpr std::size_t get_fibonacci<1u>() {
    return 1u;
}

template <std::size_t ITERATION>
std::size_t fibonacci = get_fibonacci<ITERATION>();
+2

All Articles