【问题标题】:How to get member type of boost::mpl placeholders during fold如何在折叠期间获取 boost::mpl 占位符的成员类型
【发布时间】:2017-11-01 19:16:32
【问题描述】:

假设有两个类:

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

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

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

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

所以我决定使用 MPL fold 来获取类型:

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)

我的问题是:

  • 有没有办法使用 MPL 或 Fusion 中已经定义的东西来摆脱 GetInnerKey&lt; &gt;GetInnerValue&lt; &gt;

  • 有没有办法避免使用boost::fusion::result_of::as_map&lt; &gt;

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

【问题讨论】:

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


    【解决方案1】:

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

    由于 A 类和 B 类不是元函数,因此您可能必须编写元函数来处理与 A 类和 B 类的交互。

    例如

    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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多