问题
If I use boost::mpl, lets look at the following code:
typedef fold<
vector<long,float,long>
, set0<>
, insert<_1,_2>
>::type s;
BOOST_MPL_ASSERT_RELATION( size<s>::value, ==, 2 );
How can I turn s
into a type t = boost::mpl::set<long,float>
again, such that I can use t
for selecting a partially specialized template function (on boost::mpl::set``) which extracts the element types and turns it into a std::tuple<long,float>
. It is something else
回答1:
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.
来源:https://stackoverflow.com/questions/28585599/how-to-obtain-standard-mpl-sequence-after-fold