STLの勉強
typedef std::pairItem; typedef std::vector - List; typedef typename List::iterator iterator; List v; void DoAll( void (*pFunc)(DataType&)) { for( iterator it = v.begin(); it!=v.end(); ++it) { pFunc( it->second); } }
こんな関数があったらいままでforループのまま放置していたんだけど,forループをfor_eachに置き換えられるはず.ということで挑戦してみた.
なんとなく受け取れる関数の型を変更してみる.余計なことをしている?
templatevoid DoAll( FnType Fn) { for( iterator it = v.begin(); it!=v.end(); ++it) { Fn( (*it).second); } }
select2ndがあればpairのsecond側を取得できるらしい.しかしvc8にはselect2ndが無いのでウソくさいselect2ndを定義.
struct select2nd { typename Item::second_type operator()(const Item& x) { return x.second; } }; templatevoid DoAll( FnType Fn) { select2nd get2nd; for( iterator it = v.begin(); it!=v.end(); ++it) { Fn( get2nd(*it)); } }
なんかいけそう.compose1があれば関数を合成できるらしい.しかし,compose1もvc8には実装されていない.STLportから適当に引っ張ってくる.
templateclass unary_compose { protected: _Operation1 _M_fn1; _Operation2 _M_fn2; public: unary_compose( _Operation1 fn1, _Operation2 fn2) : _M_fn1(fn1), _M_fn2(fn2) {} typename _Operation1::result_type operator()(const typename _Operation2::argument_type& __x) const { return _M_fn1(_M_fn2(__x)); } }; template inline unary_compose<_Operation1,_Operation2> compose1(const _Operation1& __fn1, const _Operation2& __fn2) { return unary_compose<_Operation1,_Operation2>(__fn1, __fn2); }
select2ndも変更する必要が出た.
struct select2nd { typedef Item argument_type; // 追加 const typename Item::second_type operator()(const Item& x) const { return x.second; } };
引数や返り値の型を自動で定義するためにSTLportは適当な親クラスを継承している? unary_functionとか.(追記:そうらしい.Effective STL 第40項を参照)
ともかく,これでfor_eachに置き換えることができた.
templatevoid DoAll( FnType Fn) { for_each( v.begin(), v.end(), compose1( Fn, select2nd())); }
vc8の使えなさ加減が勉強にはちょうどいいかもなと思った.