Boost.IteratorのSpecialized Adaptors
Specialized Adaptorsだけでも知っとくと超便利だった。
Specialじゃないのはよくわかんないけど(ぇ
とにかくすごいんだって
http://www.boost.org/doc/libs/1_45_0/libs/iterator/doc/index.html#iterator-utilities
http://shinh.skr.jp/boost/iterator_adaptors.html
Boost.Iteratorは自分でイテレータを作るのに便利なライブラリなんだけれども、
その中でもよく欲しくなるイテレータをSpecialized Adaptorsという形で手っ取り早く利用出来る。
という事でよいのか?
とりあえずtransform iteratorを試してみた。
vectorに格納されたクラスのメンバ関数を呼び出し、
戻り値の総和を得る。
#include <iostream> #include <vector> #include <numeric> #include <boost/mem_fn.hpp> #include <boost/shared_ptr.hpp> #include <boost/make_shared.hpp> #include <boost/iterator/transform_iterator.hpp> using namespace std; using namespace boost; class Dog { int age; public: explicit Dog(int age) :age(age){} int get_age()const{return age;} }; int main() { vector< shared_ptr< Dog > > dogs; dogs.push_back( make_shared<Dog>(3) ); dogs.push_back( make_shared<Dog>(4) ); dogs.push_back( make_shared<Dog>(5) ); int sum_age = accumulate( make_transform_iterator(dogs.begin(), mem_fn(&Dog::get_age)), make_transform_iterator(dogs.end(),mem_fn(&Dog::get_age)), 0); cout << sum_age << endl; }
おおーすごいすごい。めっちゃこんなことしたかった。マジ感激。
もういっちょ。
mapに格納されたすべての要素のvalueを標準出力する。
#include <iostream> #include <algorithm> #include <map> #include <boost/mem_fn.hpp> #include <boost/iterator/transform_iterator.hpp> using namespace std; using namespace boost; int main() { map<int,string> m; m.insert( make_pair( 3,"san" ) ); m.insert( make_pair( 2,"ni" ) ); m.insert( make_pair( 5,"go" ) ); copy( make_transform_iterator( m.begin() , mem_fn(&map<int,string>::value_type::second ) ), make_transform_iterator( m.end() , mem_fn(&map<int,string>::value_type::second ) ) , ostream_iterator<string>(cout,"\n") ); }
おおーすごいすごい。卒論中ずっとこれしたかった。
ところで、これとBoost.Rangeってうまく組み合わすこと出来ないんですかね?
beginとendつくてるあたりがナウくない。
と思ったらrangeアダプタなるものがあるらしいのでちょっと調べる。
追記:ちょーべんりなRangeAdaptors
http://d.hatena.ne.jp/MARISHI/20110126/1296060908