コンテナに複数のインデックスを持てるBoost.MultiIndexですが、単一のインデックスだけを持たせるだけでも便利に使えます。ここでは、std::setを置き換えて使ってみます。
std::setにユーザー定義型を格納する場合、キーの比較を自分で定義する必要があります。そしてその比較が一部のメンバ変数だけで完結する場合、std::setでは比較に必要なメンバ変数以外に、ダミーの値を入れたオブジェクトを作る必要があります。
#include <iostream> #include <set> struct X { int a = 0; int b = 0; int c = 0; X(int a, int b, int c) : a(a), b(b), c(c) {} }; struct XLess { bool operator()(const X& x, const X& y) const { return x.b < y.b; } }; int main() { std::set<X, XLess> x; x.insert({1, 3, 3}); x.insert({2, 1, 2}); x.insert({3, 4, 1}); decltype(x)::const_iterator it = x.find({-1, 1, -1}); // bだけが必要なので、aとcはダミー値 if (it != x.end()) { std::cout << it->a << std::endl; } else { std::cout << "not found" << std::endl; } }
2
Boost.MultiIndexの場合は、キー比較に使用するメンバ変数/メンバ関数を指定できるので、便利なsetとして使用できます。
#include <iostream> #include <boost/multi_index_container.hpp> #include <boost/multi_index/ordered_index.hpp> #include <boost/multi_index/member.hpp> struct X { int a = 0; int b = 0; int c = 0; X(int a, int b, int c) : a(a), b(b), c(c) {} }; using namespace boost::multi_index; using Container = multi_index_container< X, indexed_by< ordered_unique<member<X, int, &X::b>> // bをキーにする > >; int main() { Container c; c.insert({1, 3, 3}); c.insert({2, 1, 2}); c.insert({3, 4, 1}); decltype(c)::const_iterator it = c.find(1); // bの値だけ指定して検索 if (it != c.end()) { std::cout << it->a << std::endl; } else { std::cout << "not found" << std::endl; } }
2
検索が簡単にできるようになりました。