2

I have used an example from

http://en.wikipedia.org/wiki/Template_metaprogramming

const unsigned long long y = Factorial<0>::value; // == 1  

I understand the compiler can do a type check but I did not think you could put 0 where the type should be and it would be taken as the value.

Could someone explain how this is working ?

Thanks

gda2004
  • 718
  • 13
  • 32

2 Answers2

4

I did not think you could put 0 where the type should be and it would be taken as the value

The problem is the assumption: it is not "where the type should be". Rather, it is "where the template argument may be specified".

In this case, there is a non-type template argument.

It works, simply because it is a different feature than type template arguments.

It is just that way. I can recommend C++ Templates: the Complete Guide or many other books on that list to read up on the basics of C++ templates.

Community
  • 1
  • 1
sehe
  • 374,641
  • 47
  • 450
  • 633
1

In that particular example:

template <int N>
struct Factorial {
    enum { value = N * Factorial<N - 1>::value };
};

template <>
struct Factorial<0> {
    enum { value = 1 };
};

The compiler generates the classes recursively. Remember, a template by itself is not a class, only a set of rules after which classes are generated.

Initially, only Factorial<0> exists. Then you write:

const int x = Factorial<4>::value;

which tells it it needs to generate the class Factorial<4> which would translate to:

template <>
struct Factorial<4> {
    enum { value = 4 * Factorial<3>::value };
};

which again tells it to generate the class Factorial<3> and so on. This stops when it reaches Factorial<0> because it was already defined and no new classes have to be generated to compute its value member.

Basically, it moves the computation from run-time to compile-time. Note that this doesn't always work (depending on the value of N, your compiler might not support that many levels of template recursion). Also, this increases code size.

This is for the how - why this works it's because it's permitted by the standard.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625