如何将type和mpl :: vector连接到一个新的向量中

时间:2011-10-28 08:22:43

标签: c++ boost c++11 boost-mpl

我使用以下构造来创建类型的mpl矢量。

struct Struct1{
    typedef int type;
};
struct Struct2{
    typedef float type;
};
template<typename T> struct TypeReader{
    typedef typename T::type type;
};

int main()
{
    typedef bm::vector<Struct1,Struct2> MPLVector;
    typedef bm::transform<MPLVector, TypeReader<bm::_1>>::type TypeList;
    static_assert(bm::equal<TypeList, bm::vector<int,float> >::value, "Is not same");
}

到目前为止,这是按预期工作的。现在我想做的是以下

struct Struct3{
    typedef bm::vector<char,double> type;
};
typedef bm::vector<Struct1,Struct2,Struct3> MPLVector;
typedef bm::transform<MPLVector, TypeReader<bm::_1>>::type TypeList;
static_assert(bm::equal<TypeList, bm::vector<int,float,char,double> >::value, "Is not same");

这不起作用。那么我如何更改我的MetaFunction结构,它将同时适用于两者,只是一个typedef和一个mpl :: vector?
或者如果这不可能,如果我将所有类型的typedef更改为mpl向量,是否可以这样做?

2 个答案:

答案 0 :(得分:2)

我不认为这对于mpl::transform是可能的,因为它需要在源序列中从单个序列中生成多个元素。但是,可以使用mpl::fold以及mpl::is_sequence的专业化来完成此操作:

// Default case
template < typename Seq, typename TWrapper, typename Enable = void >
struct Flatten_imp
    : mpl::push_back< Seq, typename TWrapper::type >
{
};

// Sequence case
template < typename Seq, typename TWrapper >
struct Flatten_imp< 
    Seq,
    TWrapper, typename
    boost::enable_if< 
        mpl::is_sequence< typename 
            TWrapper::type 
        > 
    >::type
>   
{
    typedef mpl::joint_view< 
        Seq, typename 
        TWrapper::type 
    > type;
};

template < typename Seq >
struct Flatten
    : mpl::fold< Seq, mpl::vector<>, Flatten_imp< mpl::_, mpl::_ > >
{}

int main()
{
    typedef mpl::vector< Struct1, Struct2, Struct3 > MPLVector;
    typedef Flatten< MPLVector >::type TypeList;

    static_assert(
        mpl::equal<
            TypeList, 
            mpl::vector< int, float, char, double > 
        >::value, "Is not same");
}

如果您希望展平是递归的,可以在Flatten中调用Flatten_impl来平移序列,然后再附加;但是,请注意,只有当序列包含包装而不是直接类型时,这种递归才有效,例如

struct Struct3
{
    typedef mpl::vector< mpl::identity< char >, mpl::identity< double > > type;
}

答案 1 :(得分:0)

对于参数是Sequence(mpl vector,fusion list / vector / tuple)的情况,你必须专门化TypeReader;

在这种情况下,将 mpl::back_inserter 的强大功能与 mpl::copy 相结合(从参数的序列复制到目标类型中)

我目前没有时间来演示这个。有关如何专门处理序列的概念的提示,您可以查看boost::enable_if。但是,只需专注于template <typename> mpl::vector

即可轻松完成ProofOfConcept