从 boost::multi_index 的迭代器推导出标签

Deduce the Tag from the iterator of 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;
}

找不到正确的方法,是否可以这样做?我设计了一个类型特征来提取迭代器的标签,但我有更简单的解决方案吗?

这可以通过一些(不可否​​认的)元编程来完成:

Live Coliru Demo

#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";
}