11 Template metaprogramming

 

This chapter covers

  • Manipulating types during compilation
  • Usingconstexpr-if to perform branching at compile-time
  • Performing static introspection to check for type properties at compile-time
  • Using std::invoke and std::apply
  • Creating a DSL to define transactions for data record updates

The normal way to think of programming is that we write code, we compile it, and then the user executes the compiled binary. This is the way programming works for the most part.

With C++, we can also write a different kind of program—one that the compiler executes while it compiles our code. This might seem like a strange thing to do (how useful can it be to execute code when we have no input from the user and no data to process?). But the main point of compile-time code execution isn’t in processing data at runtime, because most of the data will become available only when we execute the compiled program, but rather in manipulating the things that are available during compilation—types and the generated code.

This is a necessity when writing optimized generic code. We might want to implement an algorithm differently, depending on the features of the type we’re given. For example, when working with collections, it’s often important to know whether the collection is randomly accessible. Depending on this, we might want to choose a completely different implementation of our algorithm.

11.1 Manipulating types at compile-time

11.1.1 Debugging deduced types

11.1.2 Pattern matching during compilation

11.1.3 Providing metainformation about types

11.2 Checking type properties at compile-time

11.3 Making curried functions

11.3.1 Calling all callables

11.4 DSL building blocks

Summary