1

Say there are two classes:

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

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

I want to use their member types to define the Fusion map:

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

So I decided to use MPL fold to obtain the 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
        <
            boost::mpl::_2 ::Key , boost::mpl::_2 ::Value
        >
    >
>::type >::type map_type;

But of course that couldn't work, as boost::mpl::_N are really metafunctions returning the Nth argument.

So, I defined two auxiliary metafunctions:

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

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

and defined the fold properly:

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)

My questions are:

  • Is there a way to get rid of GetInnerKey< > and GetInnerValue< > using something already defined in MPL or Fusion?

  • Is there a way to avoid using boost::fusion::result_of::as_map< >?

  • Is this the right approach to accomplish my intent?

Tarc
  • 3,214
  • 3
  • 29
  • 41

1 Answers1

1

Place holders are meta-functions and should be used with lazy evaluation. The ::types inside placeholders _1 & _2 are some complex types before evaluation (You could check them by typeof (with g++)).

As class A & B are not meta functions, so probably you have to write meta functions to handle interactions with class A & B.

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

qduyang
  • 353
  • 1
  • 8