使用boost :: mpl的类型组合 [英] Combination of types using boost::mpl
问题描述
我有一个类型列表,我想从中构造包含两个元素的所有组合的列表.例如:
I have a list of types, from which I want to construct the list of all combinations with two elements. For example:
namespace mpl = boost::mpl;
typedef mpl::vector<int, long> typelist;
// mpl magic...
// the wanted list is equivalent to:
typedef mpl::vector<pair<int, int>, pair<int, long>,
pair<long, int>, pair<long, long> > combinations;
在这里,pair<T1,T2>
可以是std::pair<T1,T2>
或mpl::vector<T1,T2>
.
这该怎么做?
当我们考虑pair<T1, T2> == pair<T2, T1>
时,我也有兴趣删除重复项.
谢谢.
Here, pair<T1,T2>
could be std::pair<T1,T2>
, or mpl::vector<T1,T2>
.
How to do this?
I would also be interested in removing the duplicates when we consider that pair<T1, T2> == pair<T2, T1>
.
Thanks.
推荐答案
单个类型int
与类型mpl::vector<int, long>
的组合的列表可以通过调用mpl::fold
:
The list of combinations of a single type int
with the list of types mpl::vector<int, long>
can be computed by invoking mpl::fold
:
typedef fold<
mpl::vector<int, long>, vector<>,
push_back<mpl::_1, std::pair<int, mpl::_2> >
>::type list_of_pairs;
现在,如果我们将其包装到一个单独的元函数中,并为所有初始类型列表的类型调用它,我们将得到:
Now, if we wrap that into a separate meta-function and invoke it for all types of the initial typelist we get:
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);
回答第二个问题:
answering second question:
使结果仅包含唯一元素(按照您所说的意思)要复杂得多.首先,您需要定义一个比较两个元素的元函数,并返回mpl :: true_/mpl :: false _:
Making the result containing only unique elements (in the sense you mentioned) is a bit more involved. First you need to define a meta function comparing two elements and returning 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> > >
{};
然后,我们需要定义一个元函数,尝试在给定列表中找到给定元素:
Then we need to define a meta-function which tries to find a given element in a given list:
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>
{};
现在,这可用于构建新列表,确保没有重复项被插入:
Now, this can be utilized to build a new list, making sure no duplicates are inserted:
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;
所有这些都是从我的头顶开始的,因此可能需要在此处或此处进行一些调整.但是这个想法应该是正确的.
All this is from the top of my head, so it may need some tweaking here or there. But the idea should be correct.
@rafak概述的小更正
minor corrections as outlined by @rafak
这篇关于使用boost :: mpl的类型组合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!