0

For a homework assignement I need to make a Fibonacci struct that uses a template with a single integer input and makes use of template specialisation. Online I found what I needed to make, but I couldn't have made it myself. I feel quite bad, since I don't really understand how it exactly works.

I have trouble with thinking in terms of templates. When I read about the fibonacci algorithm I thought this could be easily done with loops, but that is not allowed for the assignment.

The biggest advantage of a template is (what I've read so far): "a template allows to create a function template whose functionality can be adapted to more than one type or class without repeating the entire code for each type."

I understand what the following part does:

   template<>
    struct fibonacci<0>
    {
        static const int value = 0;
    };

    template<>
    struct fibonacci<1>
    {
        static const int value = 1;
    };

When fibonacci<0> or fibonacci<1> is called, the variable value is set to 0 or 1. The main confusion is in the part:

 template<int n>
    struct fibonacci
    {
        static const int value = fibonacci<n - 1>::value + fibonacci<n - 2>::value;
    };

Questions about individual parts:

template<int n> 

Is it correct to assume that this part indicates that only integer values are allowed in the struct?

static const int value

Why is it necessary to put static const in front of the int value?

fibonacci<n - 1>::value

Here recursion is used, so I assume that for example n = 3 the fibonacci<2> and fibonacci<1> will be called. For the fibonacci<2> the fibonacci<1> and fibonacci<0> will be called. So for every int n (until overflow) it will apply recursion until the template specialization. I don't really understand the ::value part. What does happen here?

The whole fibonacci struct:

 template<int n>
    struct fibonacci
    {
        static const int value = fibonacci<n - 1>::value + fibonacci<n - 2>::value;
    };

    template<>
    struct fibonacci<0>
    {
        static const int value = 0;
    };

    template<>
    struct fibonacci<1>
    {
        static const int value = 1;
    };
Tim
  • 415
  • 2
  • 10

2 Answers2

2

I usually think of templates as an indicator for the precompiler to copy and paste a chunk of code, while changing a specific element indicated by <>.

You can experiment with it but if a template is never called in the body of your file, then you will see that the precompiler does not even include the template (essentially it dissapears from your code).

If you are curious what happens at this pre-processing stage add the -E flag to your g++ compilation. g++ -E yourFile.cpp. If you want to capture the output in a file do g++ -E yourFile.cpp >> file

Answers:

To answer your questions:

  1. Is it correct to assume that this part indicates that only integer values are allowed in the struct?

<int n> is showing the precompiler that n can be of the type int. Experiment, and see what happens if you call the struct with something else.

  1. Why is it necessary to put static const in front of the int value?

That's a simple question to resolve with a bit of researh The static keyword and its various uses in C++. Static methods can be called on the struct itself rather than on instances of the struct.

  1. Here recursion is used, so I assume that for example n = 3 the fibonacci<2> and fibonacci<1> will be called. For the fibonacci<2> the fibonacci<1> and fibonacci<0> will be called. So for every int n (until overflow) it will apply recursion until the template specialization. I don't really understand the ::value part. What does happen here?

that just shows what static variable you are using from that structure. You are using value from fibonacci<n - 1> and etc. Similar to the way you would call a variable from an instance instance.value. This is tied to your question 2.

cstml
  • 350
  • 1
  • 12
2

Is it correct to assume that this part indicates that only integer values are allowed in the struct?

template<int n> 

There are different possible types of template parameters. You generally have to distinguish between typed and non-type template parameters. Here you have the non typed parameter case where you can specialize your base template from above for distinct integer values. For the fibonacci scheme, this is done within the abort criteria of the recursion.

Why is it necessary to put static const in front of the int value?

Shortly spoken: To have it available already within template resolution context at compile time and to not being forced to actually (OOP-)instantiate each template (which would reduce template usage here to absurdity somehow).

A bit more details:

Since C++11, you are allowed to initialize a few integral types at compile time with static const. Before that, this was not possible and you had to apply some tricks to get the compile time fibonacci algorithm working (enums where used for that for instance). At least since C++17, things can be made much clearer now for many scenarios via

static constexpr int value = 1;
Secundi
  • 1,150
  • 1
  • 4
  • 12