トップページ > コンテナとイテレータ >
サンプルの動作確認バージョン [GCC4.4/1.41.0] [VC9/1.41.0]
#include <iostream>
#include <string>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/foreach.hpp> // 以下のサンプル中でBoost.Foreach使ってます
using namespace std;
using namespace boost::multi_index;
int main()
{
typedef multi_index_container<string, // std::stringを格納するコンテナ
indexed_by<
sequenced<>, // std::list風の入れた順番アクセス
ordered_non_unique< identity<string> > // std::multiset風のソート順アクセス
// ソートは入れたstringの値そのものを使って行う
>
> container;
// まず、1つめに指定したアクセス手段(sequenced<>)を持つコンテナとして普通に使える
container c;
c.push_back("This");
c.push_back("Is");
c.push_back("A");
c.push_back("Pen");
c.push_back("That");
c.push_back("Is");
c.push_back("Also");
c.push_back("A");
c.push_back("Pen");
BOOST_FOREACH( const string& s, c )
cout << s << ' ';
cout << endl;
// 別のindex(ordered_non_unique...)でアクセスしたい場合は、get<番号>
container::nth_index<1>::type& c1 = c.get<1>();
BOOST_FOREACH( const string& s, c1 )
cout << s << ' ';
cout << endl;
// set風に使用(O(logN)で実行される)
cout << c1.count("Pen") << endl;
// set風に使用(O(logN)で実行される)
c1.erase("Is");
// あるindexから実行した操作は、別のindexにも反映されてる
BOOST_FOREACH( const string& s, c )
cout << s << ' ';
cout << endl;
}
This Is A Pen That Is Also A Pen A A Also Is Is Pen Pen That This 2 This A Pen That Also A Pen
1つのデータ集合を複数の見方でアクセスしたいことがあります。
などなど。とりあえずstd::listとかに突っ込んでおいて、ソートが必要になったら毎回std::sortをかけるとか、 存在判定は仕方ないので全要素ループを回して判定、という手はあります。 ただ、それはとても最適とは言えないので、パフォーマンス上の問題になるかもしれません。 そんな時に、multi_index_containerを使います。
「list風とset風の2通りでアクセスしたいなら、listとsetの2つ用意して両方にデータを入れていく」 というアプローチとの違いは、サンプルのeraseの例であげたように、 全てのindexでちゃんと中身の同期がとれる辺りです。単純にlistとsetを2つ用意するだけでは、 eraseをO(logN)で処理することはできません。 計算量に関しての詳細は リファレンス 参照のこと。