boost::range
range と言うことでデータを範囲として扱うライブラリです。
配列の始点と終点の位置を使用して、データに対し操作を行ないます。
配列の std::begin() と std::end() を保持しているクラスがあるってイメージだと分かりやすいかな?
まぁ説明すると怪しくなるのでソースを。
#include <iostream> #include <boost/range/algorithm/for_each.hpp> #include <boost/range/adaptor/filtered.hpp> struct is_even_impl{ bool operator()(int n) const{ return n % 2 == 0; } } is_even; int main(){ namespace adaptors = boost::adaptors; int array[] = {0, 1, 2, 3, 4, 5}; // STL for( auto it = std::begin(array) ; it != std::end(array) ; it++ ){ std::cout << *it << std::endl; }; // range auto range = boost::make_iterator_range(array); for( auto it = range.begin() ; it != range.end() ; it++ ){ std::cout << *it << std::endl; } // boost::for_each で使ってみる boost::for_each(array /* range を渡しても可 */, [](int& n){ std::cout << n << std::endl; }); // adaptors を使用して偶数だけを抽出 auto even_range = boost::adaptors::filter(array, is_even); boost::for_each(even_range, [](int n){ std::cout << n << std::endl; }); return 0; }
boost::for_each などに range としてを渡したり、直接配列を渡せたりするので比較的コードが見やすくなります。
また、boost::adaptors に用意されている関数を使用すれば range に対して操作を行うことが出来ます。
もちろん、int[] だけではなくて、std::vector でも問題なく使用することが出来ます。
同種のライブラリとして、pstade::oven があるのでそっちも合わせて使ってみると面白いかも。
( pstade::oven の方が boost::range より使い勝手がいいです)
あと range は、配列のデータを保持しているわけではなくて、配列の範囲を保持しているだけなので、元の配列の中身が変わったり、破棄されると range もぶっ飛びます。
std::vector<int> v(std::begin(array), std::end(array)); auto range = boost::make_iterator_range(v); v.clear(); range[0]; // v[0] にアクセスしようとしているので\(^o^)/
結構クセがありますが使ってみるとなかなか楽しいです。
[boost]
ver 1.44.0
[参照]
http://www.kmonos.net/alang/boost/classes/range.html
http://www.slideshare.net/faithandbrave/boost-tour-1440
[pstade]
http://p-stade.sourceforge.net/oven/doc/html/index.html
http://sourceforge.net/projects/p-stade/