You've just seen some examples of the why of template metaprogramming, and you've had a tiny glimpse of the how, but we haven't discussed when metaprogramming is appropriate. However, we've touched on most of the relevant criteria for using template metaprogramming already. As a guideline, if any three of the following conditions apply to you, a metaprogrammed solution may be appropriate.
You want the code to be expressed in terms of the abstractions of the problem domain. For example, you might want a parser to be expressed by something that looks like a formal grammar rather than as tables full of numbers or as a collection of subroutines; you might want array math to be written using operator notation on matrix and vector objects rather than as loops over sequences of numbers.
You would otherwise have to write a great deal of boilerplate implementation code.
You need to choose component implementations based on the properties of their type parameters.
You want to take advantage of valuable properties of generic programming in C++ such as static type checking and behavioral customization, without loss of efficiency.
You want to do it all within the C++ language, without an external tool or custom source code generator.