Reputation: 16354
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();
}
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.
Upvotes: 3
Views: 654
Reputation: 40633
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);
}
Upvotes: 3
Reputation: 7647
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.
Upvotes: 1