从 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;
}
找不到正确的方法,是否可以这样做?我设计了一个类型特征来提取迭代器的标签,但我有更简单的解决方案吗?
这可以通过一些(不可否认的)元编程来完成:
#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";
}
我想从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;
}
找不到正确的方法,是否可以这样做?我设计了一个类型特征来提取迭代器的标签,但我有更简单的解决方案吗?
这可以通过一些(不可否认的)元编程来完成:
#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";
}