Template metaprogramming (also template meta-programming, or just TMP) is a metaprogramming technique that involves the use of templates. It essentially works by generating temporary code as compile-time, and it is able to do work then instead of at run time. TMP is turing complete, so literally any run time instructions can be shifted to compile-time, enhancing performance.
Simple Examples[]
A common example used to demonstrate TMP, is the 'Factorial Snippet'. It is presented here:
#include <iostream> using namespace std; template<int N> struct FACTORIAL { static const int value = N * FACTORIAL<N - 1>::value; }; template <> struct FACTORIAL<0> { static const int value = 1; }; int main() { cout << FACTORIAL<4>::value << '\n'; // == 24 }
What happens in this example, is that the template FACTORIAL will be instantiated, and it's member value is accessed. To properly set value, it will instantiate itself with its value minus one. This continues until a instantiation of 0 is encountered. The template specialization handles 0 specifically, ending any infinite loops.
More Elaborate Examples[]
Loop Unrolling[]
By using recursion, TMP can hard-write the code of any loop into an executable. This means things such as for loops can be rewritten in a faster way (They are faster because there is no run time expression checking). For example, the song '99 bottle of beer' is commonly coded using a loop to count. This can be easily achieved in TMP:
#include <iostream> #include <string> using namespace std; typedef unsigned int uint; const string x = " bottles of beer"; const string a = " on the wall. "; const string v = "Take one down, pass it around! "; const string e = "No more bottles of beer on the wall. No more bottles of beer. Go to the store, buy some more! 99 bottles of beer on the wall :)"; template<uint num> void bottles() { cout << num << x << a << num << x << ". " << v << num-1 << x << '\n'; bottles<num-1>(); } template<> void bottles<0>() { cout << e; } int main() { bottles<99>(); return 0; }
![]() |