Конвертировать boost::fusion:: установите для boost::fusion::map, используя boost::fusion::fold

У меня есть набор фьюжн, и я хотел бы преобразовать его в карту фьюжн.

#include <cstdlib>
#include <iostream>

#include <boost/fusion/include/fold.hpp>
#include <boost/fusion/include/map.hpp>
#include <boost/fusion/include/make_map.hpp>
#include <boost/fusion/include/push_back.hpp>
#include <boost/fusion/include/pair.hpp>
#include <boost/fusion/container/set.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <boost/fusion/include/at_key.hpp>

struct node_base
{
    int get() {return 123;}
};
struct node_a : public node_base
{
node_a(){std::cout << "node_a::Ctor"<< std::endl;}
};
struct node_b : public node_base
{
node_b(){std::cout << "node_b::Ctor"<< std::endl;}
};
struct node_c : public node_base
{
node_c(){std::cout << "node_c::Ctor"<< std::endl;}
};

typedef ::boost::fusion::set<node_a,node_b,node_c> my_fusion_set;
my_fusion_set my_set;

struct push_back_map
{
    typedef ::boost::fusion::map<> result_type;

    template<class NODE>
    ::boost::fusion::map<> operator() (const ::boost::fusion::map<> & m, const NODE & n)
    {
    return ::boost::fusion::push_back(
        m
        , ::boost::fusion::make_pair<NODE>(n)
        );
    }
};

::boost::fusion::map<> my_map =
::boost::fusion::fold(
    my_set
    , ::boost::fusion::map<>()
    , push_back_map()
    );

struct print_map
{
    template<class P>
    void operator()(P & p) const
    {
    std::cout << p.second.get() << std::endl;
    }
};

int main()
{
    ::boost::fusion::for_each(my_map, print_map());
    std::cout << ::boost::fusion::at_key<node_a>(my_set).get() << std::endl;
    //std::cout << ::boost::fusion::at_key<node_a>(my_map).second.get() << std::endl;
    system("pause");
    return 0;
}

Этот код компилируется. Но он не мог распечатать результаты my_map. my_set построен успешно. my_map просто преобразуется из my_set с исходным типом каждого элемента в качестве ключа и его экземпляром объекта из конструктора по умолчанию в качестве значения. Мне интересно, если my_map успешно создан из fusion::fold. my_set может выполнять запрос, вызывая fusion::at_key<>, но my_map не работает для at_key<>. Спасибо!

1 ответ

Я не мог придумать краткий способ создать fusion::map отfusion::set с fold, Таким образом, этот ответ не разрешит ваш вопрос напрямую. Я отправлю это на тот случай, если это даст вам подсказку.
Как насчет подготовки списка типов (как my_types в следующем), и создание fusion::set а также fusion::map из этого списка вместо создания fusion::map от fusion::set напрямую?
Например:

namespace bf = boost::fusion;
namespace bm = boost::mpl;

typedef bm::vector<node_a,node_b,node_c> my_types;
typedef bm::fold<
          my_types
        , bm::vector<>
        , bm::push_back< bm::_1, bf::pair< bm::_2, bm::_2 > >
        >::type my_map_types;

int main() {
    bf::result_of::as_set<my_types>::type my_set;
    bf::result_of::as_map<my_map_types>::type my_map;
    std::cout << bf::at_key<node_a>(my_set).get() << std::endl;
    std::cout << bf::at_key<node_a>(my_map).get() << std::endl;
}

Вот тест на идеоне. Кстати, если тип ключа и тип значения в вашем fusion::map всегда идентичны, fusion::set встретит эту цель.

Другие вопросы по тегам