### C++ Template Metaprogramming

From my last entry I ended up writing this program while studying Template Metaprogramming:

#include <iostream> template <int N> struct Factorial { static const int result = N * Factorial<N-1>::result; }; // describes a specific case of a Factorial // We need a base case (a way to break out of the recursive loop, which in this case // is 1) template <> struct Factorial<0> { static const int result = 1; }; template <int N, int D> struct Frak { static const long Num = N; static const long Den = D; }; template <int N, typename F> struct ScalarMultiplication { typedef Frak<N*F::Num, F::Den> result; }; int main() { typedef Frak<2, 3> Two_Thirds; typedef ScalarMultiplication<2, Two_Thirds>::result Four_Thirds; std::cout << Four_Thirds::Num << "/" << Four_Thirds::Den << "\n"; return 0; }

This looks messy but I finally figured out why the executed result is 4/3, and the reason is pretty simple but hard to notice.

Starting from Main():

int main() { typedef Frak<2, 3> Two_Thirds; typedef ScalarMultiplication<2, Two_Thirds>::result Four_Thirds; std::cout << Four_Thirds::Num << "/" << Four_Thirds::Den << "\n"; return 0; }

Two_Thirds is a ~~variable~~ type and its a method call to Frak, which is a blue print to when we call our ScalarMultiplication template.

template <int N, int D> struct Frak { static const long Num = N; static const long Den = D; };

template <int N, typename F> struct ScalarMultiplication { typedef Frak<N*F::Num, F::Den> result; }; // somewhere in Main() ... int main() { // /// typedef ScalarMultiplication<2, Two_Thirds>::result Four_Thirds; // ... }

N is 2, and F is 3. But looking closely at this line:

typedef Frak<N*F::Num, F::Den> result;

Our template takes 2 parameters. 2 and 3, and the first parameter is 2 … which is then multiplied by itself to the number 4 and 3 is never calculated. So later when we print the results of this code we will get the answer **4/3**

Hopefully if anybody was confused they might find this a little bit clearer … I hope…

**EDIT: 2015/04/28**

Thanks to nicolasbrailo for clearing up the confusion I had (my bad (d’oh!)) about Two_thirds. It’s not a variable, its a type. Check out his comment below for more details. Thanks bro! ＾＾

My code after modified according to Nicolas’s comment:

#include <iostream> struct Two_thirds { static const long Num = 2; static const long Den = 3; }; int main() { std::cout << (Two_thirds::Num*Two_thirds::Num) << "/" << Two_thirds::Den << "\n"; return 0; }

Much easier!

28/04/2015 at 7:27 am

Hi Ben. Almost there!

Two_Thirds is not actually a variable, it’s a type. Just like a class is a type. If it makes it easier to see it this way, it’s almost like a copy-paste of the class definition. In fact that may be a good way to understand what that code is doing: just copy&paste the original class definition and replace its parameters by whatever is being used to instantiate the class. In this example, “typedef Frak Two_Thirds;” is exactly as if you had written this:

struct Two_Thirds {

static const long Num = 2;

static const long Den = 3;

};

If you do the same with the rest of the statements in main you should be able to quickly understand why it prints what it does.

28/04/2015 at 7:46 am

Hi Nicolas!

Thank you so much for your comment. I modified my code as you suggested:

And understood what you mean’t straight away! it really is much easier to think of it this way!

Thanks also for your tutorial! Very easy to understand ＾＾