matching 0 rather than with an inequality test, which was previously unavailable. However, the arrival in C++11 of standard library features such as std::conditional has provided another, more flexible way to handle conditional template instantiation. // Induction template<unsigned N> struct Factorial { static constexpr unsigned value = N * Factorial<N - 1>::value; }; // Base case via template specialization: template<> struct Factorial<0> { static constexpr unsigned value = 1; }; With these definitions, one can compute, say 6! at compile time using the expression Factorial<6>::value. Alternatively, constexpr in C++11 / consteval in C++20 can be used to calculate such values directly using a function at compile-time. Because of this, template meta-programming is now mostly used to do operations on types. See also Template metaprogramming Metaprogramming Monomorphization Generic programming Header-only Substitution failure is not an error Curiously recurring template pattern List of C++ template libraries References External links Demonstration of the Turing-completeness of C++ templates (Lambda calculus implementation) Generic programming Metaprogramming C++ Articles with example C++ code