boost::iterators

トップページ > コンテナとイテレータ >

abstract

必要なヘッダ
<boost/iterator/iterator_facade.hpp>, 簡単イテレータ作成
<boost/iterator/iterator_adaptor.hpp>, 既存イテレータの簡単拡張

<boost/iterator/counting_iterator.hpp> 連続整数値などをイテレータ化,
<boost/iterator/filter_iterator.hpp> 間引きイテレータ,
<boost/iterator/indirect_iterator.hpp> 二回参照外し**itイテレータ,
<boost/iterator/permutation_iterator.hpp> 並べ替えイテレータ,
<boost/iterator/reverse_iterator.hpp> 逆順イテレータ,
<boost/iterator/transform_iterator.hpp> 関数一段かましイテレータ,
<boost/iterator/zip_iterator.hpp> 複数個混ぜ合わせイテレータ,
<boost/function_output_iterator.hpp> 関数の出力を毎回返すイテレータ,
<boost/shared_container_iterator.hpp > 元コンテナをshared_ptrで捕まえとくイテレータ,
出来ること
イテレータ作成
リファレンス
en

sample

#include <iostream>
#include <algorithm>
#include <boost/iterator_adaptors.hpp>
using namespace std;
using namespace boost;

struct MyLinkedList
{
	// よくある、単方向リンクリストの定義です... 
	MyLinkedList* next;
	int           data;

	MyLinkedList( MyLinkedList* n, int d )
		: next(n), data(d) {}
	// ...ここまでは。

public:
	struct iterator
	  : iterator_adaptor<
	      iterator,
	      MyLinkedList*,        // この型をベースに
	      int,                  // この型を返す
	      forward_traversal_tag // forward_iteratorが欲しい。
	    >
	{
	  iterator( MyLinkedList* p )
	    : iterator_adaptor<iterator,
	         MyLinkedList*,int,forward_traversal_tag>( p ) {}
	  void increment()         { base_reference() = base()->next; }
	  int& dereference() const { return base_reference()->data; }
	};

	// begin, end のいい加減な定義
	iterator begin(){ return iterator(this); }
	iterator end()  { return iterator(NULL); }
};

void print(int x)
{
	cout << x << endl;
}

int main()
{
	// 100->200->300->400->500->600->end。
	MyLinkedList f( NULL, 600 );
	MyLinkedList e(  &f , 500 );
	MyLinkedList d(  &e , 400 );
	MyLinkedList c(  &d , 300 );
	MyLinkedList b(  &c , 200 );
	MyLinkedList a(  &b , 100 );

	// さっき作ったイテレータを使ってみる。
	for_each( a.begin(), a.end(), print );
	return 0;
}

出力例

100
200
300
400
500
600

etc

上の例のように、例えば increment 関数と dereference 関数を決めておいて iterator_adoptor に入れると、 あとは中で適当によきにはからって、イテレータとして使える構造体 (++できたり*できたり、value_typetypedefしてあったり)を作りあげてくれるわけです。

単に普通に普通のイテレータを作るだけでなく、例えばdereferenceの 返値を base()->data + 10; にすれば、 10ずれた値を返すような変形イテレータが完成するなどもOK。 まぁ確かに10が足せてもあまり意味はありませんが、色んな物が、 イテレータ化しておくと標準アルゴリズムを使えるようになって便利になることは ostream_iterator などの例からも想像がつく気がします。

このライブラリは、incremente,decrement,equal,dereference,… などの必要な関数を実装すると一からイテレータを作り上げてくれる iterator_facade と、既存のイテレータをベースに iterator_facadeを勝手に実装してくれて、 それを微調整する形で新しいイテレータを作るための iterator_adaptor、 そしてこの二つを使って作った具体的な汎用イテレータが幾つか、 という構成になっています。

see also

この iterator_adaptors を使って作れる汎用のイテレータが、 既にヘッダの中に幾つか用意されています。その部分に関してはこちら。

presented by k.inaba (kiki .a.t. kmonos.net) under CC0