Template metaprogramming

Template metaprogramming is a form of compile-time programming in C++, using template expressions. While a normal program would use variables of a certain type, in metaprogramming, types are variables. A metaprogram is very similar to the style of programming used in functional programming.

Functions in metaprogramming are called metafunctions. The simplest metafunction simply returns a value with no inputs; i.e. a constant. An integer constant function could be written thus:

template struct int_ { static T const value = n;  typedef T type; };

We can then express constant types such as int_ and int_.

std::cout << int_::value << '\n'; // prints 4

A simple metafunction with inputs might be one to add two ints. A first try at such a function might look like this:

template struct plus { static T const value = a + b;  typedef T type; };

Although this would indeed work as desired, it has a few problems. Firstly, 'a' and 'b' are required to be integral constants; plus, int_ > will not work. In this case one could write plus::value, int_::value>, but the requirement to reduce all inputs to integral types quickly becomes a pain, particularly since plus<> might be specialised over types which cannot be represented as such.

Instead, metafunctions are written using inheritance. In a functional language, plus would probably be written as something equivalent to:

plus (a, b) = a + b

This effectively says that plus(a,b) is a+b; in C++, the closet equivalent is:

template struct plus : int_ {}

Here we state that plus is-a int. Other than the values being types instead of variables, this is effectively identical to the functional program.

Examples
A 'pair' metaclass, which returns a type storing two other types; plus<> is specialised such that plus(pair(a, b), pair(c, d)) = pair(a + c, b + d).


 * 1) include

template struct int_ { typedef T type; static const T value = n; };

template struct plus : int_ {};

template<typename a, typename b> struct pair { typedef a first; typedef b second; };

template<typename af, typename as, typename bf, typename bs> struct plus<pair<af, as>, pair<bf, bs> > : pair< plus<af, bf>, plus<as, bs> > {};

int main { typedef int_<int, 42> a;  typedef int_<int, 3> b;   typedef pair<int_<int, 1>, int_<int, 1> > pt;

std::cout << plus<a, b>::value << '\n';

typedef plus<pair<a, b>, pt> res; std::cout << res::first::value << ", " << res::second::value << '\n'; }

A mathematical power function can be computed at compile-time with template metaprogramming.

template< int base, unsigned exponent > struct power { enum { value = base * power<base, exponent - 1>::value }; }; template struct power<base,0> { enum { value = 1 }; };