boost::iterator_adaptor
イテレータについて調べていたら、boost::iterator_adaptor を使用して、
簡単にイテレータを作れるみたいなのでやってみました。
#include <iostream> #include <boost/iterator_adaptors.hpp> #include <boost/range/algorithm/for_each.hpp> #include <boost/range/adaptor/transformed.hpp> struct vec{ struct iterator : public boost::iterator_adaptor< iterator, float*, // ベースにする型 float, // 返す型 boost::forward_traversal_tag // std::forward_iterator >{ // iterator_adaptor_ は、基底クラスで定義されている iterator(float* f) : iterator_adaptor_(f){} }; // boost::for_each で回したかったので定義 struct const_iterator : public boost::iterator_adaptor< const_iterator, const float*, float, boost::forward_traversal_tag >{ const_iterator(const float* f) : iterator_adaptor_(f){} }; iterator begin(){ return iterator(&x); } const_iterator begin() const{ return const_iterator(&x); } iterator end(){ return iterator(static_cast<float*>(&z) + 1); } const_iterator end() const{ return const_iterator(static_cast<const float*>(&z) + 1); } float x; float y; float z; }; int main(){ vec v; v.x = 1.0f; v.y = 2.0f; v.z = 3.0f; for( vec::iterator it = v.begin() ; it != v.end() ; it++ ){ std::cout << *it << std::endl; } std::for_each(std::begin(v), std::end(v), [](float f){ std::cout << f << std::endl; }); // const_iterator を定義しておく必要がある boost::for_each(v, [](float f){ std::cout << f << std::endl; }); // adaptor も使用可 using boost::adaptors::transformed; struct add{ float operator()(float f) const{ return f += 1.0f; } typedef float result_type; }; v|transformed(add()); return 0; }
おお、これは楽だ。
boost::range も併用して使えるようになるのでかなり便利になります。
素晴らしい。
[boost]
ver 1.44.0
[参照]
http://www.kmonos.net/alang/boost/classes/iterators.html
http://d.hatena.ne.jp/faith_and_brave/20100305/