Question

Now that my previous question has a solution, more questions arise.

I want to use the wrap_into_container meta-function with boost::mpl::transform, e.g.:

#include <vector>
#include <list>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/mpl.hpp>
#include <boost/mpl/transform.hpp>

namespace container
{
    template <typename T> struct vector { typedef std::vector<T> type; };
    template <typename T> struct list   { typedef std::list<T> type; };
}

template<typename T, template <typename> class Container>
struct wrap_into_container
{
    typedef typename Container<T>::type type;
};

int main()
{
    namespace fusion = boost::fusion;
    namespace mpl = boost::mpl;

    typedef fusion::vector<int, float, int> vec_type;
    typedef mpl::transform< vec_type, wrap_into_container<mpl::_1, container::vector> >::type wrapped_vec_type;

    wrapped_vec_type w;
    return w.size();
}

Link to coliru

But it seems like I cannot pass a template template parameter into mpl::transform ...

How can I solve this? Please provide a C++03 solution, since I cannot use C++11.

Was it helpful?

Solution

In boost::mpl, higher order functions are written by passing a fixed type with an internal apply template member (known as a metafunction class), rather than through the use of template-template parameters. Live Example.

#include <vector>
#include <list>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/mpl.hpp>
#include <boost/mpl/transform.hpp>
#include <iostream>

namespace container
{
    struct vector {
        template<typename T> struct apply {
            typedef std::vector<T> type;
        };
    };
    struct list   {
        template <typename T> struct apply {
            typedef std::list<T> type;
        };
    };
}

template<typename T, typename ContainerMaker>
struct wrap_into_container
{
    typedef typename ContainerMaker::template apply<T>::type type;   
};

int main()
{
    namespace fusion = boost::fusion;
    namespace mpl = boost::mpl;

    typedef fusion::vector<int, float, int> vec_type;
    typedef mpl::transform<
        vec_type,
        wrap_into_container<mpl::_1, container::vector>
    >::type wrapped_vec_type;

    wrapped_vec_type w;
    std::cout << size(w) << "\n";
    return size(w);

}

OTHER TIPS

I don't know boost::mpl, so I can only speculate from what I've seen in the documentation.

I think what you need is

template<template <typename> class Container>
struct wrap_into_container
{
    template<typename T>
    struct map
    {
        typedef typename Container<T>::type type;
    };
};

Followed by

typedef wrap_into_container<container::vector>::template map<mpl::_1> fun;
typedef transform<vec_type, fun>::type wrapped_vec_type;

In this case, fun is a class of the form C<mpl::_1> where C is a class template, and whose ::type is std::vector<mpl::_1>. I think this is what mpl::transform expects for its type map.

My only test is with my own version of transform, which works with template template arguments instead of placeholders for the type map. Check live example, where transform is defined using C++11 but the remaining part is C++03. In this example, I am only using

wrap_into_container<container::vector>::template map

as a template template argument to my transform, without the placeholder <mpl::_1>.

I hope this helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top