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

PrevUpHomeNext

Tutorial

To start using typeof include the typeof header:

#include <boost/typeof/typeof.hpp>

To deduce the type of an expression at compile time use the BOOST_TYPEOF macro:

namespace ex1
{
    typedef BOOST_TYPEOF(1 + 0.5) type;

    BOOST_STATIC_ASSERT((is_same<type, double>::value));
}

In the dependent context use BOOST_TYPEOF_TPL instead of BOOST_TYPEOF:

namespace ex2
{
    template<class T, class U>
    BOOST_TYPEOF_TPL(T() + U()) add(const T& t, const U& u)
    {
        return t + u;
    };

    typedef BOOST_TYPEOF(add('a', 1.5)) type;

    BOOST_STATIC_ASSERT((is_same<type, double>::value));
}

The above examples are possible because the Typeof Library knows about primitive types, such as int, double, char, etc. The Typeof Library also knows about most types and templates defined by the Standard C++ Library, but the appropriate headers need to be included to take advantage of this:

#include <boost/typeof/std/utility.hpp>

namespace ex3
{
    BOOST_AUTO(p, make_pair(1, 2));

    BOOST_STATIC_ASSERT((is_same<BOOST_TYPEOF(p), pair<int, int> >::value));
}

Here <boost/typeof/std/utility.hpp> includes <utility> and contains knowledge about templates defined there. This naming convention applies in general, for example to let the Typeof Library handle std::vector, include <boost/typeof/std/vector.hpp>, etc.

To deduce the type of a variable from the expression, this variable is initialized with, use the BOOST_AUTO macro (or BOOST_AUTO_TPL in a dependent context:

#include <boost/typeof/std/string.hpp>

namespace ex4
{
    BOOST_AUTO(p, new int[20]);

    BOOST_STATIC_ASSERT((is_same<BOOST_TYPEOF(p), int*>::value));
}

Both BOOST_TYPEOF and BOOST_AUTO strip top-level qualifiers. Therefore, to allocate for example a reference, it has to be specified explicitly:

namespace ex5
{
    string& hello()
    {
        static string s = "hello";
        return s;
    }

    BOOST_AUTO(&s, hello());
}

To better understand this syntax, note that this gets expanded into:

BOOST_TYPEOF(hello()) &s = hello();

If your define your own type, the Typeof Library cannot handle it unless you let it know about this type. You tell the Typeof Library about a type (or template) by the means of "registering" this type/template.

Any source or header file where types/templates are registered has to contain the following line before any registration is done:

#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()

After this a type can be registered:

namespace ex6
{
    struct MyType
    {};
}

BOOST_TYPEOF_REGISTER_TYPE(ex6::MyType)

The registration must be done from the context of global namespace; fully qualified type name has to be used.

Any number of types can be registered in one file, each on a separate line.

Once your type is registered, the Typeof Library can handle it in any context:

namespace ex6
{
    typedef BOOST_TYPEOF(make_pair(1, MyType())) type;

    BOOST_STATIC_ASSERT((is_same<type, pair<int, MyType> >::value));
}

A template is registered by specifying its fully qualified name, and describing its parameters. In the simplest case, when all parameters are type parameters, only their number needs to be specified:

namespace ex7
{
    template<class T, class U>
    struct MyTemplate
    {};
}

BOOST_TYPEOF_REGISTER_TEMPLATE(ex7::MyTemplate, 2)

namespace ex7
{
    typedef BOOST_TYPEOF(make_pair(1, MyTemplate<int, ex6::MyType>())) type;

    BOOST_STATIC_ASSERT((is_same<type,
        pair<int, MyTemplate<int, ex6::MyType> >
    >::value));
}

When a template has integral template parameters, all parameters need to be described in the preprocessor sequence:

namespace ex8
{
    template<class T, int n>
    struct MyTemplate
    {};
}

BOOST_TYPEOF_REGISTER_TEMPLATE(ex8::MyTemplate, (class)(int))

namespace ex8
{
    typedef BOOST_TYPEOF(make_pair(1, MyTemplate<ex7::MyTemplate<ex6::MyType, int>, 0>())) type;

    BOOST_STATIC_ASSERT((is_same<type,
        pair<int, MyTemplate<ex7::MyTemplate<ex6::MyType, int>, 0> >
    >::value));
}

Please see the reference for more details.


PrevUpHomeNext