やあみんな元気にしてるかい。忘年会の会場となる店が今日やっとこさ決まって今年の幹事を任されているおじさんとしてもやっとこさ一息ついているところだよ。ところで for_eachでだって、前回値を使ったループ処理が可能だ。これでコンテナを引数にとるアルゴリズムを記述すべきでないことを推奨する根拠が個人的にまた一つ強化された感じだ。
以下の、前回値ループ処理を実現するクラス、PrevsMustGoでは、二乗値数列の差分が奇数数列となることを実際に求めて確認してるサンプルだよ。
いやー、標準アルゴリズムはいいねぇ。ファンクタを工夫すれば何だってできそうだ。そしてコード量も減りコードも見やすくなって、しかも理解しやすくなる。一部のつまらないバグも減るだろうし、パフォーマンスも上がるというわけだ。
#include <iostream> #include <algorithm> #include <vector> #include <iterator> #include <functional> using namespace std; int main( void ) { vector< int > il(10); { // 二乗の数を il に生成 struct power2{ power2( void ):_cnt(-1){} int operator()( void ){ return (++_cnt)*_cnt; } int _cnt; }; generate( il.begin(), il.end(), power2() ); } vector< int > idv; { // 二乗の数の差分値を、idv に格納 struct PrevsMustGo { PrevsMustGo( void ){ _prev=0; } int operator()( const int a ) const { int tmp= a-_prev; _prev = a; return tmp; } mutable int _prev; }; transform( il.begin(), il.end(), back_inserter( idv ), PrevsMustGo() ); } // 結果を確認(以下はvc++だからこう書けるのな) for each( int i in il ){ cout<< i<< ", "; } cout<<endl; for each( int i in idv ){ cout<< i<< ", "; } cout<<endl; return 0; } // 出力: //0, 1, 4, 9, 16, 25, 36, 49, 64, 81, //0, 1, 3, 5, 7, 9, 11, 13, 15, 17,