Home > Articles > Programming > C/C++

C++ Templates: Metaprograms

  • PrintPrint
  • Share ThisShare This
  • DiscussDiscuss
Close Window

Nicolai M. JosuttisDavid Vandevoorde

Learn more…

Sorry, this author hasn't written any articles.

Sorry, this author doesn't have anything for sale.

Sorry, this author hasn't posted any blogs.

C++ Templates: The Complete Guide

This chapter is from the book
C++ Templates: The Complete Guide

Nicolai M. Josuttis and David Vandevoorde examine metaprogramming, or “programming a program.” Learn how to lay out code that the programming system executes to generate new code that implements the functionality you really want.

Metaprogramming consists of “programming a program.” In other words, we lay out code that the programming system executes to generate new code that implements the functionality we really want. Usually the term metaprogramming implies a reflexive attribute: The metaprogramming component is part of the program for which it generates a bit of code/program.

Why would metaprogramming be desirable? As with most other programming techniques, the goal is to achieve more functionality with less effort, where effort can be measured as code size, maintenance cost, and so forth. What characterizes metaprogramming is that some user-defined computation happens at translation time. The underlying motivation is often performance (things computed at translation time can frequently be optimized away) or interface simplicity (a metapro-gram is generally shorter than what it expands to) or both.

Metaprogramming often relies on the concepts of traits and type functions as developed in Chapter 15. We therefore recommend getting familiar with that chapter prior to delving into this one.

17.1 A First Example of a Metaprogram

In 1994 during a meeting of the C++ standardization committee, Erwin Unruh discovered that templates can be used to compute something at compile time. He wrote a program that produced prime numbers. The intriguing part of this exercise, however, was that the production of the prime numbers was performed by the compiler during the compilation process and not at run time. Specifically, the compiler produced a sequence of error messages with all prime numbers from two up to a certain configurable value. Although this program wasn’t strictly portable (error messages aren’t standardized), the program did show that the template instantiation mechanism is a primitive recursive language that can perform nontrivial computations at compile time. This sort of compile-time computation that occurs through template instantiation is commonly called template metaprogramming.

As an introduction to the details of metaprogramming we start with a simple exercise (we will show Erwin’s prime number program later on page 318). The following program shows how to compute at compile time the power of three for a given value:

// meta/pow3.hpp

#ifndef POW3_HPP
#define POW3_HPP

//primary template to compute 3 to the N;
template<int N>
class Pow3 {
  public:
    enum { result = 3 * Pow3<N-1>::result };
};

//full specialization to end the recursion}
template<>
class Pow3<0> {
  public:
    enum { result = 1 };
};


#endif // POW3_HPP

The driving force behind template metaprogramming is recursive template instantiation.1 In our program to compute 3N, recursive template instantiation is driven by the following two rules:

  1. 3N = 3 * 3N - 1

  2. 30 = 1

The first template implements the general recursive rule:

template<int N>
 class Pow3 {
  public:
    enum { result = 3 * Pow3<N-1>::resykt };
 };

When instantiated over a positive integer N, the template Pow3>< needs to compute the value for its enumeration value result. This value is simply twice the corresponding value in the same template instantiated over N-1.

The second template is a specialization that ends the recursion. It establishes the result of Pow3<0>

template<>
class Pow3<0> {
  public:
    enum { result = 1 };
};

Let’s study the details of what happens when we use this template to compute 37 by instantiating Pow3<7>:

#include <iostream>
#include "pow3b.hpp"

int main()
{
    std::cout << "Pow3<7>::result = " << Pow3<7>::result
              << '\n';
}

First, the compiler instantiates Pow3<7>. Its result is

   3 * Pow3<5>::result

Thus, this requires the instantiation of the same template for 6. Similarly, the result of Pow3<6> instantiates Pow3<5>, Pow3<4>, and so forth. The recursion stops when Pow3<> is instantiated over zero which yields one as its result.

The Pow3<> template (including its specialization) is called a template metaprogram. It describes a bit of computation that is evaluated at translation time as part of the template instantiation process. It is relatively simple and may not look very useful at first, but there are situations when such a tool comes in very handy.

  • Share ThisShare This
  • Your Account

Discussions

Make a New Comment

You must log in in order to post a comment.

Related Resources

Danny KalevMinutes from the October 2009 Meeting
By Danny Kalev on November 19, 2009 No Comments

The minutes from the Santa Cruz (October 2009) meeting are available here. Even if you're not a language layer at heart, I encourage you to read them.

Danny KalevA Reader's Opinion on Attributes
By Danny Kalev on October 20, 2009 No Comments

In August I dedicated a series to the debate about C++0x attributes. I believe that it covered the subject in a balanced and detailed way, but I keep getting complaints from C++ users who don't like attributes for various reasons. Here's a recent email I received from a Polish C++ programmer. While it  doesn't represent my opinion about attributes -- I'm rather neutral about this feature and consider it a "solution waiting for a problem" -- but it suggests that attributes are still a highly controversial issue that will haunt C++ for a long time. The email is quoted here with minor edits that and as usual, with all private details removed.

Danny KalevFollowup: The Web 2.0 Guy I Ain't
By Danny Kalev on October 16, 2009 1 Comment

Almost a year ago, I posted here The Web 2.0 Guy I Ain't. People wonder whether I still resist all those Web 2.0 features and technologies at the end of 2009.

See All Related Blogs

Informit Network