通过调用 mpl::fold
,可以计算单个类型 int
与类型列表 mpl::vector<int, long>
的所有组合:
typedef fold<
mpl::vector<int, long>, vector<>,
push_back<mpl::_1, std::pair<int, mpl::_2> >
>::type list_of_pairs;
现在,如果我们将其封装为一个单独的元函数,并对初始类型列表的所有类型调用它,我们会得到:
typedef mpl::vector<int, long> typelist;
template <typename T, typename Result>
struct list_of_pairs
: mpl::fold<typelist, Result,
mpl::push_back<mpl::_1, std::pair<T, mpl::_2> > >
{};
typedef mpl::fold<
typelist, mpl::vector<>, mpl::lambda<list_of_pairs<mpl::_2, mpl::_1> >
>::type result_type;
BOOST_MPL_ASSERT(
mpl::equal<result_type,
mpl::vector4<
std::pair<int, int>, std::pair<int,long>,
std::pair<long,int>, std::pair<long,long>
> >::value);
编辑:回答第二个问题:
使结果仅包含唯一元素(按照您所述的意义)需要更多的工作。首先,您需要定义一个元函数,比较两个元素并返回mpl :: true_ / mpl :: false_:
template <typename P1, typename P2>
struct pairs_are_equal
: mpl::or_<
mpl::and_<
is_same<typename P1::first_type, typename P2::first_type>,
is_same<typename P1::second_type, typename P2::second_type> >,
mpl::and_<
is_same<typename P1::first_type, typename P2::second_type>,
is_same<typename P1::second_type, typename P2::first_type> > >
{};
接下来我们需要定义一个元函数,它会尝试在给定的列表中查找给定的元素:
template <typename List, typename T>
struct list_doesnt_have_element
: is_same<
typename mpl::find_if<List, pairs_are_equal<mpl::_1, T> >::type,
typename mpl::end<List>::type>
{};
现在,这可以用于创建一个新列表,确保不插入重复项:
typedef mpl::fold<
result_type, mpl::vector<>,
mpl::if_<
mpl::lambda<list_doesnt_have_element<mpl::_1, mpl::_2> >,
mpl::push_back<mpl::_1, mpl::_2>, mpl::_1>
>::type unique_result_type;
这些都是我脑海中的想法,可能需要进行一些微调。但是这个思路应该是正确的。
编辑:根据@rafak的概述进行了一些小修正。
list_doesnt_have_element
中,请将end<List>
替换为typename end<List>::type
,对于find_if也是如此。另外,我不得不将BOOST_STATIC_ASSERT(is_same<
替换为BOOST_MPL_ASSERT((mpl::equal<
,并在末尾添加另一个括号。如果有人可以编辑答案,我将删除此评论。 - rafak