「イテレータ、auto,範囲for文」

 動的配列のすべての要素をループ処理するには、通常の配列をループ処理するのと同じ構文
を使える。けれども、C++STLの他の多くのコレクションは(例えばlistmapがそうだが)、
配列の構文をサポートしない。
そいう、他のコンテナをループ処理する方法として、コレクションの要素をたどるのを援助する
イテレータ(iterator)というオブジェクトがある。C++ STL(standard template library)のコレクションは、どれも
イテレーターをサポートする。どのコレクションにも、最初の要素へのイテレーターを返すbegin関数と、
最後の要求へのイテレーターを返すend関数がある。イテレーターの型名は、
そのコレクションの型名に::iteratorを加えたものだ。例えば次のコードはリストを作成した後、
イテレーターを使ってリストの各要素をループする。



 このようにイテレーターは、ポインタと同じように*で間接参照される。他のコレクションも、
これと同じ構文でループ処理することができる
ただしマップの場合、実際にイテレーターが指すのはstd::pairなので、イテレーターが
マップの要素を指している時、そのキーにアクセスするにはfirstを、値にアクセスするには
secondを使う必要がある。先ほど見たmonthのマップの場合、イテレーターによって要素を
取得してそのデータを出力するには、次のコードを使える。



イテレーターのために長い型名をタイプするのは面倒だが、C++11で、その苦行を緩和する
autoキーワードが導入された。autoと書けば、コンパイラーが変数の型を、代入された値から
推定してくれる。例えばbegin関数は非常に特定された型のイテレーターを返すので、autoは、
その正しい型を推定できる。
 autoを使うと、リストのループを次のように書きなせる。



 autoを使うのに性能上のペナルティはないが、そいうコードは理解しにくいというプログラマーもいる(慣れろ)
この本のコードでは、読みやすさを改善される時にだけautoを使っている。
 たとえばautoを使っても、イテレーター経由でループするコードは不細工だ。他の多くの言語
は、コレクションのループする処理にforeach構造を提供している。C++11にも同様な構造があって、
それは範囲for文のループ(range-base for loop)と呼ばれている。numbersリストを
範囲for文で処理するには、次の構文を使う。



 このループは、リストの各要素をループ処理しながら、それぞれの要素のコピーを作る。ただし、
コレクションの要素を書き換えたい時は、参照渡しにすることも可能だ。同様に、const参照も使える。
 範囲for文でも、型の代わりにautoを使うことができる。ただし、明示的な型を使う場合と
同じく、これも各要素のコピーを作る。ただし、もし必要ならば、autoとともにconst&を使うことも出来る。
 範囲for文の欠点は、ループの中でコレクションの要素を追加したり削除したり出来ないことだ。そいう振る舞いが必要な時は、
他の形式のループを使わなければならない。

【戻る】