使用boost :: mpl的类型组合 [英] Combination of types using boost::mpl

查看:157
本文介绍了使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆