Über den praxisrelevanten Einsatz der Template-Metaprogrammierung

Seite 4: Exkurs: TMP kurz und bündig

Inhaltsverzeichnis

Template Metaprogramming erlaubt es, zur Compilezeit Berechnungen auf Ganzzahlen und, besonders interessant, Typen vorzunehmen. Die Sprachkonstrukte sind allesamt C++-Templates, und die Sprache ist rein funktional.

C++ besitzt keine eingebaute Syntax für diese Art der Programmierung, weshalb sich TMP einer Anzahl von Konventionen bedient, die maßgeblich die Boost.MPL (Meta-Programming Library) definiert hat. Dazu gehört die Konvention, Ableitungen zur Definition von Metafunktionen zu verwenden:

template <typename Arg1, typename Arg2>
struct mf
  : /* implement here */ {};

Das wiederum ist aus der Konvention geboren, den Rückgabewert einer Metafunktion mf<T,S> durch einen geschachtelten typedef mf<T,S>::type oder, falls das Ergebnis kein Typ ist, sondern eine Ganzzahl, durch mf<T,S>::value zurückzuliefern.

Das TMP-Äquivalent zu "Hello, World" ist die Berechnung der Fakultät:

// recursion:
template <int N>
fact { enum { value = N * fact<N-1>::value }; };
// termination condition:
template <>
fact<0> { enum { value = 1 }; };
// test:
BOOST_STATIC_ASSERT(( fact<5>::value == 120 ));

Verglichen mit dem, was die MPL liefert, ist das jedoch Programmierung auf Assemblerebene. Ein Beispiel:

// a (MPL) vector with three types:
typedef mpl::vector<char,int,short> vec;
// a metafunction, wrapping the sizeof operator:
template <typename T>
struct sizeof_
  : mpl::size_t<sizeof(T)> {};
// a binary meta function for comparing by sizeof:
template <typename T, typename S>
struct less_size
    : mpl::less< sizeof_<T>, sizeof_<S> > {};
// sort 'vec' according to size of types:
typedef mpl::sort< vec, less_size<_,_> >::type sorted;
// check that we get what we've expected:
BOOST_MPL_ASSERT((
  equal< sorted, vector<char,short,int> >
));

Das ist schon ähnlich mächtig wie die STL für "normales" C++.