Max Martinevsky
Max Martinevsky

Reputation: 11

How to instantiate templates from mpl::vector?

How a can transform vector of stl containers?

I have:

typedef boost::mpl::vector<std::vector<boost::mpl::_1>, std::deque<boost::mpl::_1> > Containers;

Heed to transform it to:

typedef boost::mpl::vector<std::vector<int>, std::deque<int> > IntContainers;

How to do it, what should be used instead "xxx" ?

typedef boost::mpl::transform
<
    Containers,
    boost::mpl::**xxx**<boost::mpl::_1 , int>
>::type IntContainers;

Upvotes: 1

Views: 111

Answers (1)

Barry
Barry

Reputation: 303770

transform takes an argument that needs to be a Lambda Expression. The simplest kind of lambda expression is a Metafunction Class, so let's go with that. We need a class that has a nested class template named apply that yields a type named type. In our case, apply will take an "argument" that is itself a lambda expression (in our example vector<_1> and <deque<_1>) and we need to just apply it. That is:

template <typename Arg>
struct call_with {
    template <typename T>
    struct apply {
        using type = typename boost::mpl::apply<T, Arg>::type;
    };  
};

using R = boost::mpl::transform<
    Containers,
    call_with<int>
>::type;

It's probably possible to write all of call_with inline in transform with clever use of placeholders, but I find this a lot easier to understand.

Edit Apparently here's the clever use of placeholders:

using R = boost::mpl::transform<
    Containers,
    apply1<_1, int>
>::type;

I do not understand why apply1 works where apply does not.

Upvotes: 1

Related Questions