Rokiのチラ裏

学生による学習のログ

Tuple-based for loops

あまり体調が良くないのだが、適度に頭を使わなくても書けるネタを見つけたのでアップロード。P0589R0にインスパイアされて、そういえば書いておくと楽だろうなと今頃思ったので自分でも書いた。tupleの展開には、いつも再起したりindex_sequence使ったりapplyしたりしていたが。

P0589R0には、本提案によってinitializer-listとparameter packの相互作用により、複数の型を持つパラメータパックなどを適用できるようになるとある*1。…とここでinitializer_listの話題があったので、どうせなら対応しようと思い対応してみた。また、for_each中にカウントしたい場合があるかもしれないとも思ったので、そのようなものも。まぁ、こういうのは結構前からあるとは思うのだが、一応こう使える。

std::vector<int> v{10,20,30};
const auto disp=[](const auto&){/* */}; 
const auto counter=[](const auto&,std::size_t){/* */}; // valueとカウンター値

srook::for_each(v.begin(),v.end(),disp); // 普通のfor_each
srook::for_each(v,disp); // range base for_each
srook::for_each(std::make_tuple(42,'a',42.5f),disp); // tuple
srook::for_each({10,20,30},disp); // initializer_list

srook::for_each(srook::make_counter(v.begin(),v.end()),counter); // カウント.デフォルト値は0
srook::for_each(srook::make_counter(v.begin(),v.end(),5),counter); // 5からカウントを始める
srook::for_each(srook::make_counter(v),counter); // rangeで指定
srook::for_each(srook::make_counter(std::make_tuple(42,'a',42.5f)),counter); // tuple
srook::for_each(srook::make_counter({10,20,30}),counter); // initializer_list

まあ、boost.fusionを使えば良いという気はする。

*1:P0589R0- Interaction with initializer lists and parameter packs