Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

Chapter 42. Boost.Typeof

Arkadiy Vertleyb

Peder Holt

Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt )

Table of Contents

Motivation
Tutorial
Reference
AUTO, AUTO_TPL
COMPLIANT
INCREMENT_REGISTRATION_GROUP
INTEGRAL
LIMIT_FUNCTION_ARITY
MESSAGES
LIMIT_SIZE
REGISTER_TYPE
REGISTER_TEMPLATE
TEMPLATE
TYPEOF, TYPEOF_TPL
TYPEOF_NESTED_TYPEDEF, TYPEOF_NESTED_TYPEDEF_TPL
Other considerations and tips
Native typeof support and emulation
The three participating parties
Supported features
What needs to be registered?
Limitations
Contributed By:
Acknowledgements

Motivation

Today many template libraries supply object generators to simplify object creation by utilizing the C++ template argument deduction facility. Consider std::pair. In order to instantiate this class template and create a temporary object of this instantiation, one has to supply template parameters, as well as parameters to the constructor:

std::pair<int, double>(5, 3.14159);

To avoid this duplication, STL supplies the std::make_pair object generator. When it is used, the types of template parameters are deduced from supplied function arguments:

std::make_pair(5, 3.14159);

For the temporary objects it is enough. However, when a named object needs to be allocated, the problem appears again:

std::pair<int, double> p(5, 3.14159);

The object generator no longer helps:

std::pair<int, double> p = std::make_pair(5, 3.14159);

It would be nice to deduce the type of the object (on the left) from the expression it is initialized with (on the right), but the current C++ syntax does not allow for this.

The above example demonstrates the essence of the problem but does not demonstrate its scale. Many libraries, especially expression template libraries, create objects of really complex types, and go a long way to hide this complexity behind object generators. Consider a nit Boost.Lambda functor:

_1 > 15 && _2 < 20

If one wanted to allocate a named copy of such an innocently looking functor, she would have to specify something like this:

lambda_functor<
    lambda_functor_base<
        logical_action<and_action>,
        tuple<
            lambda_functor<
                lambda_functor_base<
                    relational_action<greater_action>,
                    tuple<
                        lambda_functor<placeholder<1> >,
                        int const
                    >
                >
            >,
            lambda_functor<
                lambda_functor_base<
                    relational_action<less_action>,
                    tuple<
                        lambda_functor<placeholder<2> >,
                        int const
                    >
                >
            >
        >
    >
>
f = _1 > 15 && _2 < 20;

Not exactly elegant. To solve this problem (as well as some other problems), the C++ standard committee is considering a few additions to the standard language, such as typeof/decltype and auto (see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1607.pdf).

The typeof operator (or decltype, which is a slightly different flavor of typeof) allows one to determine the type of an expression at compile time. Using typeof, the above example can be simplified drastically:

typeof(_1 > 15 && _2 < 20) f = _1 > 15 && _2 < 20;

Much better, but some duplication still exists. The auto type solves the rest of the problem:

auto f = _1 > 15 && _2 < 20;

The purpose of the Boost.Typeof library is to provide a library-based solution, which could be used until the language-based facility is added to the Standard and becomes widely available.


PrevUpHomeNext