base_itをベースとなるiterator,itをbase_itにadaptorを適用したiterator,fを関数とします.transform_iteratorは*itがf(*base_it)になるようにしてくれます.この形式はitがinput iteratorであるときに相性が良い形式ですが,output iteratorを似たような形でadaptするのは若干しんどいです.もちろん,fが*itに対する参照を返せばある程度のことはできますが,この方式は限界がある.むしろ,*it = v(vはある値)という代入式が*base_it = f(v)を意味するようにした方が圧倒的に自由度が高い.そういうiterator adaptorが欲しい.でも無い.なので実装しました.
l_transform_iterator.hpp
使い方はtransform_iteratorとほとんど一緒ですが,与える関数の意味が逆になります.transform_iteratorはiteratorが出力する値に対して関数が適用されますが,このl_transform_iteratorはiteratorに入力されようとする値に対して関数が適用されます.それだけ.
以下,これを使ったサンプル.
#include <map> #include <string> #include <utility> #include <algorithm> #include <iterator> #include <iostream> #include <boost/lambda/lambda.hpp> #include "l_transform_iterator.hpp" using namespace std; using namespace boost; using namespace boost::lambda; using namespace cry; int main(int argc, char *argv[]) { typedef map<int, string> name_map; name_map h0515, h0518; // 5月15日の試合でヒット打った選手 h0515.insert(pair<int, string>(9, "藤本")); h0515.insert(pair<int, string>(3, "八木")); h0515.insert(pair<int, string>(53, "赤星")); h0515.insert(pair<int, string>(7, "今岡")); h0515.insert(pair<int, string>(24, "桧山")); h0515.insert(pair<int, string>(14, "アリアス")); h0515.insert(pair<int, string>(44, "関本")); h0515.insert(pair<int, string>(39, "矢野")); h0515.insert(pair<int, string>(5, "沖原")); h0515.insert(pair<int, string>(32, "久慈")); // 5月18日の試合でヒット打った選手 h0518.insert(pair<int, string>(53, "赤星")); h0518.insert(pair<int, string>(7, "今岡")); h0518.insert(pair<int, string>(6, "金本")); h0518.insert(pair<int, string>(24, "桧山")); h0518.insert(pair<int, string>(14, "アリアス")); h0518.insert(pair<int, string>(44, "関本")); h0518.insert(pair<int, string>(39, "矢野")); // 両日でヒット打った選手は? // 注:比較にpairの比較を使って,代入時にfirstを切り落とす set_intersection( h0515.begin(), h0515.end(), h0518.begin(), h0518.end(), make_l_transform_iterator( ostream_iterator<string>(cout, "\n"), &_1 ->* &name_map::value_type::second)); return 0; }
終わり.