Here's a full example. I called the metafunction Unify
but obviously you can call it whatever you want.
How it works is quite simple, it simply removes elements from the input sequence one at a time and builds up a variadic list and dumps them into the desired sequence type at the end.
#include <boost/mpl/set.hpp>
#include <boost/mpl/front.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/insert.hpp>
#include <boost/mpl/erase_key.hpp>
#include <tuple>
template <template <class...> class OutSeqType,
class Sequence,
std::size_t nSeqSize,
class ... Elements>
struct Unify
{
typedef typename boost::mpl::front<Sequence>::type Next;
typedef typename Unify<
OutSeqType,
typename boost::mpl::erase_key<Sequence, Next>::type,
nSeqSize - 1, Next, Elements...>::type type;
};
template <template <class...> class OutSeqType,
class Sequence,
class ... Elements>
struct Unify<OutSeqType, Sequence, 0ul, Elements...>
{
typedef OutSeqType<Elements...> type;
};
int main()
{
typedef boost::mpl::insert<
boost::mpl::insert<
boost::mpl::insert<
boost::mpl::set<>,
int>::type,
float>::type,
int*>::type Set;
typedef Unify<
std::tuple,
Set,
boost::mpl::size<Set>::type::value
>::type Set2;
//This compile error will print the type of Set2
Set2::asdfl;
}
For some reason I'm not sure about I couldn't use pop_front
on a set
so I used erase_key
instead. This restricts it to associative containers, but it could be generalized to any type of container with a little more work. I'll leave that as an exercise.
boost::mpl
is a bit archaic since it predates C++11's variadic templates and template aliases. You might have an easier time using something more modern like Eric Niebler's Tiny Meta-Programming Library. E.g.,template<class...Ts> using unique_tuple = meta::apply_list<meta::quote<std::tuple>, meta::unique<meta::list<Ts...>>>;
will computestd::tuple<long, float>
fromunique_tuple<long,float,long>
. – Passade