user1777820
user1777820

Reputation: 768

Boost MPL Types Vs Templates

I'm fairly new to Boost MPL (and meta programming in general) and I think I'm confused by the idea of templates vs types. A simple example I'm working with is trying to compute the length of a vector. The following compiles fine:

typedef mpl::vector_c< int, 0, 1, 2, 3, 4, 5, 6, 7 > myVector;

struct TestSize
{
    template <typename mySequence> struct apply
    {
        typedef mpl::size<mySequence> type;
    };
};

typedef TestSize::apply<myVector>::type result;

but if I add "::type" to the result of the size computation, like this:

struct TestSize
{
    template <typename mySequence> struct apply
    {
        typedef mpl::size<mySequence>::type type;
    };
};

typedef TestSize::apply<myVector>::type result;

then I get the error "error: nontype "boost::mpl::size::type [with Sequence=mySequence]" is not a type name".

Is this a situation where the template parameter is not deduced because it is in a nested namespace? Adding to my confusion is the fact that the following compiles:

struct TestSize
{
    template <typename mySequence> struct apply
    {
        typedef mpl::size<mySequence> type;
        typedef mpl::range_c<int, 0, type::type::value> myRange;
    };
};

typedef TestSize::apply<myVector>::type result;
typedef TestSize::apply<textureIndices>::myRange range;

Why can I do "type::type::value" there, but not "size< mySequence>::type" on the line before?

Upvotes: 0

Views: 151

Answers (1)

SergeyA
SergeyA

Reputation: 62583

The reason you are having this error is because you need to use typename like this (in the inner apply):

struct TestSize
{
    template <typename mySequence> struct apply
    {
        typedef typename mpl::size<mySequence>::type type; // <-- here!
    };
};

The need for the typename in this context arises from the way compilers compile templates. When the template is initially pre-compiled, it needs to be sematically correct. However, compiler doesn't know (at this point) that mpl::size<mySequence>::type is indeed a type. At this point it doesn't know what mySequence is, and how mpl::size is specified for mySequence. And by default it assumes it is not a type. So you need to hint it.

And now your probably understand why type::type::value works fine - compiler by default thinks value is not a type, you are not trying to use it as a type, and compiler is happy. By the way, if you were to define value as a type for a certain specialization, you would have a funny compilation error if this specialization is used!

Upvotes: 3

Related Questions