Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

Click here to view the latest version of this page.
Front Page / Tutorial: Metafunctions and Higher-Order Metaprogramming / Details

Details

By now you should have a fairly complete view of the fundamental concepts and language of both template metaprogramming in general and of the Boost Metaprogramming Library. This section reviews the highlights.

Metafunction forwarding.
The technique of using public derivation to supply the nested type of a metafunction by accessing the one provided by its base class.
Metafunction class.
The most basic way to formulate a compile-time function so that it can be treated as polymorphic metadata; that is, as a type. A metafunction class is a class with a nested metafunction called apply.
MPL.

Most of this book's examples will use the Boost Metaprogramming Library. Like the Boost type traits headers, MPL headers follow a simple convention:

#include <boost/mpl/component-name.hpp>

If the component's name ends in an underscore, however, the corresponding MPL header name does not include the trailing underscore. For example, mpl::bool_ can be found in <boost/mpl/bool.hpp>. Where the library deviates from this convention, we'll be sure to point it out to you.

Higher-order function.
A function that operates on or returns a function. Making metafunctions polymorphic with other metadata is a key ingredient in higher-order metaprogramming.
Lambda expression.
Simply put, a lambda expression is callable metadata. Without some form of callable metadata, higher-order metafunctions would be impossible. Lambda expressions have two basic forms: metafunction classes and placeholder expressions.
Placeholder expression.

A kind of lambda expression that, through the use of placeholders, enables in-place partial metafunction application and metafunction composition. As you will see throughout this book, these features give us the truly amazing ability to build up almost any kind of complex type computation from more primitive metafunctions, right at its point of use:

// find the position of a type x in some_sequence such that:
//         x is convertible to 'int'
//      && x is not 'char'
//      && x is not a floating type
typedef mpl::find_if<
      some_sequence
    , mpl::and_<
          boost::is_convertible<_1,int>
        , mpl::not_<boost::is_same<_1,char> >
        , mpl::not_<boost::is_float<_1> >
      >
    >::type iter;

Placeholder expressions make good on the promise of algorithm reuse without forcing us to write new metafunction classes. The corresponding capability is often sorely missed in the runtime world of the STL, since it is often much easier to write a loop by hand than it is to use standard algorithms, despite their correctness and efficiency advantages.

The lambda metafunction.
A metafunction that transforms a lambda expression into a corresponding metafunction class. For detailed information on lambda and the lambda evaluation process, please see the the MPL reference manual.
The apply metafunction.
A metafunction that invokes its first argument, which must be a lambda expression, on its remaining arguments. In general, to invoke a lambda expression, you should always pass it to mpl::apply along with the arguments you want to apply it to in lieu of using lambda and invoking the result "manually."
Lazy evaluation.
A strategy of delaying evaluation until a result is required, thereby avoiding any unnecessary computation and any associated unnecessary errors. Metafunctions are only invoked when we access their nested ::types, so we can supply all of their arguments without performing any computation and delay evaluation to the last possible moment.