反復子とは
イテレータ(iterator)とも言います。iterateは英語で繰り返すという意味を持ちます。なのでiteratorは反復子ですね。
ここでは反復子に統一します。
反復子はコンテナへのアクセス機能を提供します。
本項ではvectorコンテナを例に解説しますが、他のどのコンテナでも共通して使うことが出来ます。
反復子の用法はポインタに似ています。
反復子はコンテナのある要素を指します。
ではポインタを使えばいいじゃないかという思うかもしれません。
しかしポインタでは大変なのです。何故でしょう。
コンテナは基本的に動的に要素を追加することが出来ます。
要素を後から追加する際、メモリ上の元の要素の直後に格納できるとは限りません。
その為、コンテナは前後の要素のアドレスのポインタを保持しています。
なので、これを解決するための仕組みを持った反復子が必要なのです。
反復子による参照
まずは反復子の生成方法を見てみましょう。
【コンテナの型】<【要素の型】>::iterator 【反復子名】
例えば、int型の要素を持つvectorの反復子ivは以下のようになります。
vector<int>::iterator iv
これで反復子は定義できましたが、ポインタと同様、これだけではどこも指していない為、動きません。
コンテナのメンバ関数を使って位置を指定します。
ここではint型の要素を持つvectorオブジェクトvを指すとします。
iv = v.begin()
begin()関数はvectorコンテナの先頭の要素を返す関数です。
これで反復子を初期化できました。
さらに、vectorコンテナの最後の一つ後の要素を指す関数にend()があります。
最後の要素の一つ後というのが重要です。
例えば10個の要素を持つコンテナなら添え字は0~9ですね。
一番最後は9なのでその一つ後の10を返します。
反復子はポインタと同様に値を参照することができます。
*iv
先ほどivは先頭の要素を代入したので、このようにすると先頭の要素の値を見ることになります。
また、インクリメントすることで次の要素を指すことになりますね。
これらを使うとループ文で全要素を参照できます。
for (iv = v.begin(); iv != v.end(); iv++) cout << *iv << endl;
このようになります。
反復子による格納
続いて反復子を使ってデータを格納する方法です。
*iv = 1
ivが先頭を示しているとしたらこれは先頭の要素に1を代入しています。
これもインクリメントすれば指定した要素まで飛ぶことができます。
これを使えば途中の要素を変更することができます。
サンプルコード
上記の内容をまとめたサンプルが以下になります。
iterator_sample.cpp
#include <iostream> #include <vector> using namespace std; int main(void) { vector<double> v(5); vector<double>::iterator iv; iv = v.begin(); *iv = 0.2; ++iv; *iv = 0.4; ++iv; *iv = 0.6; iv++; *iv = 0.8; iv++; *iv = 1.0; for (iv = v.begin(); iv != v.end(); iv++) cout << *iv << endl; return 0; }
要素数5のdouble型を格納するvectorオブジェクトに値を代入し、表示しています。
vectorオブジェクトの定義の際、要素数を指定することができます。