C++ template metaprogramming

Can anyone explain to me how does the following output of '5' came about? And how does this particular program works. Because I couldn't for the life of me figure out why it's 5 or how this program works.. Thanks!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>

template <long long N>
class Fib
{
public:
	static const long long value = Fib<N - 1>::value +
						 Fib<N - 2>::value;
};

template <>
class Fib<1>
{
public:

	static const long long value = 1;
};

template <>
class Fib<2>
{
public:
	
	enum : long long { value = 1 };
};

int main()
{

	// std::cout << 5 << std::endl;
	std::cout << Fib<5>::value << std::endl;
}
Last edited on
You can think of a template as instructions for the compiler to figure out how to write functions (or classes) for you.

The compiler sees this:

1
2
3
4
5
6
int main()
{

	// std::cout << 5 << std::endl;
	std::cout << Fib<5>::value << std::endl;
}


It sees this: Fib<5>::value

Uh oh. That's a template. I'd better create something. What does the Fib<Some_Number> template look like? Looks like this:

1
2
3
4
5
6
7
template <long long N>
class Fib
{
public:
	static const long long value = Fib<N - 1>::value +
						 Fib<N - 2>::value;
};


so what does Fib<5> look like? Looks like this:
1
2
3
4
5
6
class Fib
{
public:
	static const long long value = Fib<4>::value +
						 Fib<3>::value;
};


So now what does your code looks like? Looks kind of like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// THIS IS THE Fib<5> CLASS
class Fib
{
public:
         // HERE IS Fib<5>::value
	static const long long value = Fib<4>::value +
						 Fib<3>::value;
};

int main()
{

	// std::cout << 5 << std::endl;
	std::cout << Fib<5>::value << std::endl;
}


So what's Fib<5>::value? it's Fib<4>::value + Fib<3>::value

Uh-oh. Fib<4>::value and Fib<3>::value need some template magic. Better do that.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// THIS IS THE Fib<3> CLASS
class Fib
{
public:
         // HERE IS Fib<3>::value
	static const long long value = Fib<2>::value +
						 Fib<1>::value;
};

// THIS IS THE Fib<4> CLASS
class Fib
{
public:
         // HERE IS Fib<4>::value
	static const long long value = Fib<3>::value +
						 Fib<2>::value;
};

// THIS IS THE Fib<5> CLASS
class Fib
{
public:
         // HERE IS Fib<5>::value
	static const long long value = Fib<4>::value +
						 Fib<3>::value;
};

int main()
{

	// std::cout << 5 << std::endl;
	std::cout << Fib<5>::value << std::endl;
}


So what's Fib<5> value ?

It's Fib<4>::value + Fib<3>::value,
which is ( Fib<3>::value + Fib<2>::value ) + ( Fib<2>::value + Fib<1>::value )
which is ( Fib<2>::value + Fib<1>::value + Fib<2>::value ) + ( Fib<2>::value + Fib<1> )

So your code now looks like this:
1
2
3
4
5
int main()
{
	// std::cout << 5 << std::endl;
	std::cout << Fib<2>::value + Fib<1>::value + Fib<2>::value + Fib<2>::value + Fib<1>::value << std::endl;
}


What's Fib<2>::value? That's an easy one:
1
2
3
4
5
6
class Fib<2>
{
public:
	
	enum : long long { value = 1 }; // HERE'S Fib<2>::value
};


Fib<1> is similarly easy.

So your code now looks like this:

1
2
3
4
5
int main()
{
	// std::cout << 5 << std::endl;
	std::cout << 1+1 +1 + 1 + 1 << std::endl;
}





Last edited on
Topic archived. No new replies allowed.