如何在折叠期间获取boost :: mpl占位符的成员类型

时间:2017-11-01 19:16:32

标签: c++ metaprogramming boost-mpl boost-fusion

假设有两个类:

struct A
{
    using Key = int;
    using Value = char;
};

struct B
{
    using Key = char;
    using Value = float;
};

我想使用他们的成员类型来定义Fusion地图:

typedef boost::fusion::map
<
    boost::fusion::pair< int , char > ,
    boost::fusion::pair< char , float >
> desired_type;

所以我决定使用MPL折叠来获得类型:

typedef boost::fusion::result_of::as_map< boost::mpl::fold
<
    boost::mpl::vector< A , B > ,

    boost::fusion::map< > ,

    boost::fusion::result_of::push_back
    <
        boost::mpl::_1 ,
        boost::fusion::result_of::make_pair
        <
            boost::mpl::_2 ::Key , boost::mpl::_2 ::Value
        >
    >
>::type >::type map_type;

但当然这不起作用,因为boost::mpl::_N实际上是返回第N个参数的元函数。

所以,我定义了两个辅助元函数:

template< class T >
struct GetInnerKey
{
    typedef typename T::Key type;
};

template< class T >
struct GetInnerValue
{
    typedef typename T::Value type;
};

并正确定义了折叠:

typedef boost::fusion::result_of::as_map< boost::mpl::fold
<
    boost::mpl::vector< A , B > ,

    boost::fusion::map< > ,

    boost::fusion::result_of::push_back
    <
        boost::mpl::_1 ,
        boost::fusion::result_of::make_pair
        <
            GetInnerKey< boost::mpl::_2 > , GetInnerValue< boost::mpl::_2 >
        >
    >
>::type >::type map_type;

Live at Coliru

我的问题是:

  • 有没有办法摆脱GetInnerKey< >GetInnerValue< >使用已在MPL或Fusion中定义的内容?

  • 有没有办法避免使用boost::fusion::result_of::as_map< >

  • 这是实现我意图的正确方法吗?

1 个答案:

答案 0 :(得分:1)

占位符是元函数,应该与惰性求值一起使用。占位符_1&amp;中的 :: type s _2是评估前的一些复杂类型(您可以通过 typeof (使用g ++)检查它们。)

作为A级和A级B不是元函数,所以可能你必须编写元函数来处理与A类和A类的交互。乙

e.g。

template <class PT1, class... PTs>
struct map_type
{
    typedef typename map_type<PTs...>::type pts_map;
    typedef typename boost::fusion::result_of::as_map<
        boost::fusion::joint_view<
            boost::fusion::map<
                boost::fusion::pair< typename PT1::Key, typename PT1::Value>
            >,
            pts_map
        >
    >::type type;
};

template <class PT1>
struct map_type<PT1>
{
    typedef boost::fusion::map<
        boost::fusion::pair< typename PT1::Key, typename PT1::Value>
    > type;
};

Live on Coliru