これがBoost.MultiIndexの最もよく使われるであろうユースケース。
MultiIndexのインデックス指定方法は2つあり、まずはインデックスを整数値で指定する方法。
#include <iostream> #include <string> #include <algorithm> #include <boost/mem_fn.hpp> #include <boost/multi_index_container.hpp> #include <boost/multi_index/member.hpp> #include <boost/multi_index/ordered_index.hpp> using namespace boost::multi_index; struct person { int id; std::string name; int age; person(int id, const std::string& name, int age) : id(id), name(name), age(age) {} void print() const { std::cout << id << "," << name << "," << age << std::endl; } }; typedef multi_index_container< person, indexed_by< ordered_unique<member<person, int, &person::id> >, ordered_unique<member<person, std::string, &person::name> >, ordered_unique<member<person, int, &person::age> > > > dictionary; template <int Index, class Container> void print_by_index(const Container& c) { typename Container::nth_index<Index>::type const& i = c.get<Index>(); std::for_each(i.begin(), i.end(), boost::mem_fn(&person::print)); std::cout << std::endl; } int main() { dictionary dict; dict.insert(person(3, "Akira", 30)); dict.insert(person(1, "Millia", 20)); dict.insert(person(4, "Johnny", 10)); print_by_index<0>(dict); // id順 print_by_index<1>(dict); // name順 print_by_index<2>(dict); // age順 }
1,Millia,20 3,Akira,30 4,Johnny,10 3,Akira,30 4,Johnny,10 1,Millia,20 4,Johnny,10 1,Millia,20 3,Akira,30
もうひとつは、インデックスをタグで指定する方法。
#include <iostream> #include <string> #include <algorithm> #include <boost/mem_fn.hpp> #include <boost/multi_index_container.hpp> #include <boost/multi_index/member.hpp> #include <boost/multi_index/ordered_index.hpp> using namespace boost::multi_index; struct person { int id; std::string name; int age; person(int id, const std::string& name, int age) : id(id), name(name), age(age) {} void print() const { std::cout << id << "," << name << "," << age << std::endl; } }; struct id{}; struct name{}; struct age{}; typedef multi_index_container< person, indexed_by< ordered_unique<tag<id>, member<person, int, &person::id> >, ordered_unique<tag<name>, member<person, std::string, &person::name> >, ordered_unique<tag<age>, member<person, int, &person::age> > > > dictionary; template <class Tag, class Container> void print_by_tag(const Container& c) { typename Container::index<Tag>::type const& i = c.get<Tag>(); std::for_each(i.begin(), i.end(), boost::mem_fn(&person::print)); std::cout << std::endl; } int main() { dictionary dict; dict.insert(person(3, "Akira", 30)); dict.insert(person(1, "Millia", 20)); dict.insert(person(4, "Johnny", 10)); print_by_tag<id>(dict); print_by_tag<name>(dict); print_by_tag<age>(dict); }
インデックスに名前を付けられるので、タグを優先的に使ったほうがよさそう。