このエントリーをはてなブックマークに追加

 

C++ iterator(イテレータ) 入門
Copyright (C) 2014 by Nobuhide Tsuda

 

※ イラスト提供:かわいいフリー素材集「いらすとや」様

C++ iterator(イテレータ) とは

  • iterator(イテレータ)とは抽象化されたポインタのことで、コンテナ の要素を指し、移動、要素を参照・変更することが出来る。
  • iterator(イテレータ)は日本語では「反復子」と訳されるが、最近では「イテレータ」と呼ぶことが多いと思う。
  • もともとは、外部ライブラリであった STL(Standard Template Library) で導入されたものだが、現在では C++ の標準に取り込まれている。
  • コンテナクラスとSTLアルゴリズムを結びつける結合器的な役割を持つ
    • STLアルゴリズムも現在は標準アルゴリズムとしてC++に取り込まれている
    • イテレータを引数にとる、便利なアルゴリズムが多数用意されている
  • 標準アルゴリズムを使用せず、イテレータ経由でコンテナを操作し、なんらかの処理を行うことも可能
    • これは、自分でアルゴリズムを書いていることに相当する
  • ランダムアクセス、両方向移動可能、前方向のみ移動可能という種別がある。コンテナクラスにより決まる
    • vector::iterator, array::iterator はランダム・アクセス可能
    • list::iterator は両方向移動可能
    • forward_list::iterator は前方向のみ移動可能
  • 要素を修正できるイテレータ(iterator)、参照のみが可能なイテレータ(const_iterator)がある
  • begin(), end() で(非const)イテレータを取得、cbegin(), cend() で const イテレータを取得出来る
  • 末尾から先頭に向かって逐次処理を行う場合は rbegin(), rend() を使うことも出来る
  • ++ 演算子によりイテレータを進めることが出来る
  • ランダム・アクセス可能、両方向移動可能であれば、-- 演算子によりイテレータを前に戻すことが出来る
  • ランダム・アクセス可能であれば、+=n, -=n でイテレータを移動出来る。
  • ランダム・アクセス可能であれば、itr2 - itr1 のように、差分を取ることが出来る。
  • 通常のポインタもランダムアクセス可能なイテレータとして扱うことが出来る。
  • * 演算子により、イテレータが指す先を参照・変更することが出来る
  • イテレータを使って、アルゴリズムを記述しておくと、コンテナクラスに依存しないようにできる(場合がある)
    • 完全にコンテナクラスに依存しないように書けるというのは幻想である

逆引きiterator(イテレータ)

  • int 型の要素を持つ std::vector へのイテレータを宣言する方法は?
  •     std::vector<int>::iterator itr;
    
  • int 型の要素を持つ std::vector への const なイテレータを宣言する方法は?
  •     std::vector<int>::const_iterator itr;
    
  • int 型の要素を持つ std::vector v の先頭を指すイテレータを宣言する方法は?
  •     std::vector<int>::iterator itr = v.begin();
    

    または

        auto itr = v.begin();        // 推奨
    
  • int 型の要素を持つ std::vector v の末尾(最後の要素の次)を指すイテレータは?
  •     v.end();        //  型は vector<int>::iterator
    
  • int 型の要素を持つ std::vector v の先頭を指す const なイテレータを宣言する方法は?
  •     std::vector<int>::const_iterator itr = v.cbegin();
    

    または

        auto itr = v.cbegin();      // 推奨
    
  • int 型の要素を持つ std::vector v の末尾(最後の要素の次)を指す const なイテレータは?
  •     v.cend();           // 型は vector<int>::const_iterator
    
  • イテレータ itr をひとつ進める方法は?
  •     ++itr;
    
  • イテレータ itr をひとつ前に戻す方法は?
  •     --itr;
    
  • ランダム・アクセス可能なイテレータ itr を n 進める方法は?
  •     itr += n;
    
  • ランダム・アクセス可能なイテレータ itr を n 前に戻す方法は?
  •     itr -= n;
    
  • first と last 間の要素数を求める方法は?
  •     std::distance(first, last);
    
  • イテレータ itr の指す先の要素を参照する方法は?
  •     *itr
    
  • イテレータ itr の指す先の要素に val を代入する方法は?
  •     *itr = val;
    
  • イテレータを使って vector<int> v の要素を最初から最後まで参照する方法は?
  •     for(auto itr = v.begin(); itr != v.end(); ++itr) {
            *itr;
        }
    
  • イテレータを使って vector<int> v の要素を最後から最初まで参照する方法は?
  •     for(auto itr = v.rbegin(); itr != v.rend(); ++itr) {
            *itr;
        }
    
  • 範囲 [first, last) を全て処理する方法は?
  •     while( first != last ) {
            何らかの処理;
            ++first;
        }
    
  • ランダム・アクセス可能なイテレータ first, last を使って、範囲 [first, last) の要素をソートする方法は?
  •     std::sort(first, last);
    
  • イテレータ first, last を使って、範囲 [first, last) の要素の合計を計算する方法は?
  •     std::accumulate(first, last, 0);
    
  • イテレータ first, last を使って、範囲 [first, last) の要素順序を反転させる方法は?
  •     std::reverse(first, last);
    
  • イテレータ first, last を使って、範囲 [first, last) の要素値が val の個数を数える方法は?
  •     std::count(first, last, val);