Как получить тип члена boost::mpl для заполнения
Скажем, есть два класса:
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;
Мои вопросы:
Есть ли способ избавиться от
GetInnerKey< >
а такжеGetInnerValue< >
используя что-то уже определенное в MPL или Fusion?Есть ли способ избежать использования
boost::fusion::result_of::as_map< >
?Это правильный подход для достижения моих целей?
1 ответ
Заполнители являются мета-функциями и должны использоваться с ленивой оценкой. ::type внутри заменителей _1 и _2 - это несколько сложных типов перед вычислением (вы можете проверить их по 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;
};