Template metaprogramming is a way to make the compiler do calculations or decisions at compile time instead of at runtime.
- It uses templates (like class or typename) to write code that generates other code automatically.
- This can make programs faster, because some work is done before the program runs.
Example 1: Computing Factorial at Compile Time
#include <iostream>
using namespace std;
// Template metaprogram to calculate factorial
template <int N> struct Factorial
{
static const int value = N * Factorial<N - 1>::value;
};
// Base case
template <> struct Factorial<0>
{
static const int value = 1;
};
int main()
{
cout << "Factorial of 5 is: " << Factorial<5>::value << endl;
return 0;
}
Output
Factorial of 5 is: 120
Explanation: The template recursively computes the factorial during compilation. Factorial<0> serves as the base case that stops the recursion, so Factorial<5>::value is evaluated by the compiler as 5 × 4 × 3 × 2 × 1 = 120 before the program runs.
Example 2: Computing Powers of Two at Compile Time
#include <iostream>
using namespace std;
template <int n> struct funStruct
{
enum
{
val = 2 * funStruct<n - 1>::val
};
};
template <> struct funStruct<0>
{
enum
{
val = 1
};
};
int main()
{
cout << funStruct<8>::val << endl;
return 0;
}
Output
256
Explanation: The template recursively computes the value during compilation. funStruct<0> acts as the base case, and funStruct<8>::val is evaluated by the compiler as (2^8 = 256) before the program executes.
Working of Template Metaprogramming
Template metaprogramming relies on the following features of C++:
1. Templates Can Accept Non-Type Parameters
Templates can accept constant values as parameters.
template<int N>
struct Example { };
Here, N is a compile-time constant.
2. Compile-Time Constants
Values defined using enum, static const, or constexpr can be evaluated during compilation.
enum { value = 10 };
3. Template Instantiation
Whenever the compiler encounters a new template argument, it creates a new instance of that template.
For example:
Factorial<5>::value
causes the compiler to instantiate:
Factorial<5>
Factorial<4>
Factorial<3>
Factorial<2>
Factorial<1>
Factorial<0>
Advantages of Template Metaprogramming
Template metaprogramming provides several benefits:
- Eliminates certain computations from runtime.
- Improves performance by shifting work to compile time.
- Enables compile-time validation and optimization.
- Forms the basis of many generic C++ libraries.
Limitations of Template Metaprogramming
Traditional template metaprogramming also has some drawbacks:
- Syntax can be difficult to understand.
- Compilation time may increase significantly.
- Compiler error messages can become complex.
- Debugging compile-time code is challenging.