Template computations
As templates are instantiated at compile times, they were used to optimize code by removing the computational burden from runtime and transferring it to the compile time. It is hence a classic example of the precomputation optimization technique. As templates are allowed to take an integer argument and may contain static class members, the following recursive technique can be applied:
// recursion step
template <unsigned int Base, unsigned int Exp>
struct Power
{
static const
unsigned long long result = Base * Power<Base, Exp - 1>::result;
};
// base case
template <unsigned int Base>
struct Power<Base, 0>
{
static const unsigned long long result = 1;
};
std::cout << " --> 2**5 = " << Power<2, 5>::result << std::endl;
Today, we wouldn't use recursion anymore, but that's how it was done. The preceding example is a simple exponentiation, but we could do more complicated stuff using that technique. For example, using our Power template, we could compute the N first digits of PI using the Bailey-Borwein-Plouffe formula (see https://en.wikipedia.org/wiki/Bailey-Borwein-Plouffe_formula). Try to do it, if you feel like it!