std::for_eachにループカウンタを入れる方法 - 名古屋313の日記
元ネタの質問というのがどういうものなのか見てないですけど、
よくある要望としては、for_eachでコンテナの要素とループカウンタの両方がほしい、というところじゃないかと思います。
この要望に対する回答としては、以下のように、RangeとCounting Rangeを綴じ合わせ、
要素にループカウンタの情報を付加する、というものになります。
Ovenの場合はcountingとzippedを使う
#include <iostream> #include <vector> #include <pstade/oven/algorithm.hpp> #include <pstade/oven/initial_values.hpp> #include <pstade/oven/zipped.hpp> #include <pstade/oven/counting.hpp> namespace oven = pstade::oven; void disp(boost::tuples::tuple<int, int> t) { int x, i; boost::tie(x, i) = t; std::cout << x << "," << i << std::endl; } int main() { const std::vector<int> v = oven::initial_values(3, 1, 4); oven::for_each(boost::make_tuple(v, oven::counting(0, v.size())) | oven::zipped, &disp); }
3,0 1,1 4,2
Boost.RangeExの場合はcounting_rangeとcombineを使う
#include <iostream> #include <vector> #include <boost/range/algorithm/for_each.hpp> #include <boost/range/combine.hpp> #include <boost/range/counting_range.hpp> #include <boost/assign/std/vector.hpp> void disp(boost::tuples::tuple<int, int> t) { int x, i; boost::tie(x, i) = t; std::cout << x << "," << i << std::endl; } using namespace boost::assign; int main() { std::vector<int> v; v += 3, 1, 4; boost::for_each( boost::combine(v, boost::counting_range(0, static_cast<int>(v.size()))), &disp); }
Ovenの場合には、boost::zip_iteratorが異なる要素数をもつRange同士のイテレーションをサポートしてくれれば
oven::countingの代わりにoven::iterationを使えて、(sizeを計算しなくていいので)さらに効率よくできそうですね。
RangeExにはiterationないです。
追記:
ScalaにはzipWithIndexというズバリそのものな関数が用意されているようです。
http://www.scala-lang.org/docu/files/api/scala/Iterator.html#zipWithIndex
http://twitter.com/bleis/statuses/13316669682