Выведите тег из итератора boost::multi_index

Я хотел бы вывести тег из итератора boost::multi_index, возможно ли это?

псевдокоды

struct digital_base_struct
{
    digital_base_struct();

    std::string description_;
    //.......   
};

typedef boost::multi_index::multi_index_container<
digital_base_struct,
boost::multi_index::ordered_unique<
boost::multi_index::tag<description_tag>,
boost::multi_index::member<digital_base_struct,
    std::string,&digital_base_struct::description_>
>,
//.......

> digital_base_table;

int main()
{
    typedef digital_base_table<description_tag>::type descript_table;
    typedef descript_table::iterator descript_it;
    //is it possible to deduce the tag 
    //in another word, could I get the type "description_tag" from iterator?
    typedef descript_it::tag tag;
}

Не могу найти способ сделать это правильно, возможно ли это сделать? Я разрабатываю черту типа для извлечения тега итератора, но есть ли у меня более простое решение?


person user3689849    schedule 13.05.2015    source источник


Ответы (1)


Это можно сделать с помощью некоторого (правда, нетривиального) метапрограммирования:

Демо-версия Coliru

#include <boost/mpl/at.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/insert.hpp>
#include <boost/mpl/map.hpp>
#include <boost/mpl/pair.hpp>

template<typename Map,typename Index>
struct add_to_iterator_to_tag_map:
  boost::mpl::fold<
    typename Index::tag_list,
    Map,
    boost::mpl::insert<
      boost::mpl::_1,
      boost::mpl::pair<typename Index::iterator,boost::mpl::_2>
    >
  >
{};

template<typename MultiIndexContainer>
struct iterator_to_tag_map:
  boost::mpl::fold<
    typename MultiIndexContainer::index_type_list,
    boost::mpl::map<>,
    add_to_iterator_to_tag_map<boost::mpl::_1,boost::mpl::_2>
  >
{};

template<typename MultiIndexContainer,typename Iterator>
struct tag_from_iterator:
  boost::mpl::at<
    typename iterator_to_tag_map<MultiIndexContainer>::type,
    Iterator
  >
{};

// testing

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/identity.hpp>
#include <iostream>

using namespace boost::multi_index;

struct struct1{};
struct struct2{};
struct struct3{};
struct struct4{};

typedef multi_index_container<
 int,
 indexed_by<
  ordered_unique<tag<struct1>,identity<int>>,
  ordered_unique<tag<struct2,struct3>,identity<int>>,
  ordered_unique<tag<struct4>,identity<int>>
 >
> multi_t;

int main()
{
  using iterator1=multi_t::nth_index<0>::type::iterator;
  using iterator2=multi_t::nth_index<1>::type::iterator;
  using iterator3=multi_t::nth_index<2>::type::iterator;

  std::cout<<typeid(tag_from_iterator<multi_t,iterator1>::type).name()<<"\n";
  std::cout<<typeid(tag_from_iterator<multi_t,iterator2>::type).name()<<"\n";
  std::cout<<typeid(tag_from_iterator<multi_t,iterator3>::type).name()<<"\n";
}
person Joaquín M López Muñoz    schedule 13.05.2015