可能ならば常にiteratorを使おう

だって、速いから。配列なんかよりずっとね。
特にstd::vectoriteratorや、boost::arrrayのiteratorね!


(追記:id:faith_and_brave さんの指摘でbeginやendが「実装上」ポインタになるということを追記しました)


……と、C++漬けの日々ですがSTLもBoostも使っている中で、
なかなかiteratorを使って貰えなかったりします。
純粋に「iteratorってよくわからない」とか「長い」とか「遅そう」なんていうイメージがあるみたいなんですが、
なんのなんの、iteratorは配列より速いですよ?
安全ですよ?
typedefできますよ?
配列に比べて劣るところなし!


勿論、速度に関しては最適化をしてなかったり、
debug_iteratorだと配列とは勝負になりませんが、
iteratorがきちんと最適化されたときはポインタ演算に成り下がるので、
std::vectorやboost::arrayの

v.begin();は、実装上はポインタ(配列の開始アドレス)になり、(型としては異なる
v.end();も実装上ポインタ(配列の終端アドレス)になるので、(型としては異なる

for (std::vector<int>::iterator it = v.begin(); it != v.end(); ++it) {
    ...
}

はアドレス比較ループになるわけです。
安全で(デバッグ版STLなどを使うときはイテレータチェックが入る)、
速くて、
様々なアルゴリズムが適応できるiteratorを使わない理由がないよね!

C++を使うならまず
iteratorを憶えましょう〜。
くらいの存在。
const_iteratorとか、reverse_iteratorとかconst_reverse_iteratorとかは後でいいから
まずiteratorを憶えよう!

#include <cstdio>
#include <ctime>
#include <vector>

using namespace std;

class Stopwatch
{
public:
    Stopwatch() : clock_(clock()) {}
    ~Stopwatch() { printf("tick:%d\n", static_cast<int>(clock()-clock_)); }
private:
    clock_t clock_;
};

enum {
    kSize = 100000
};

int a[kSize];
std::vector<int> v;

int main()
{
    const int size = kSize;
    for (int i=0; i < size; ++i ) {
        v.push_back(i);
    }
    int total = 0;
    {
        Stopwatch sw;
        for (std::vector<int>::iterator it = v.begin(); it != v.end(); ++it) {
            total += (*it);
        }
    }
    {
        Stopwatch sw;
        for (int i = 0; i < kSize; ++i) {
            total += a[i];
        }
    }
    printf("%d\n", total);
    return 0;
}

Effective STL―STLを効果的に使いこなす50の鉄則

Effective STL―STLを効果的に使いこなす50の鉄則

  • 作者: スコットメイヤーズ,Scott Meyers,細谷昭
  • 出版社/メーカー: ピアソンエデュケーション
  • 発売日: 2002/01
  • メディア: 単行本
  • 購入: 6人 クリック: 122回
  • この商品を含むブログ (91件) を見る