イテレータのループを書くときのスタイル

しょうもないちゃあしょうもない話なんですけど、C++イテレータのループを書くときに、ループの初期化と終了条件を書く行が長くなりがちなので、改行のスタイルをどうするかよく悩みます。
※ループの中でvectorに変化ない場合、終了条件を毎回end()を呼び出して検査するのは無駄な関数呼び出しになってしまう可能性があるので、変数に入れています。→C++ Coding Standards 9項「時期尚早に最不適化してしまわない」

改行しない

for(std::vector<MyClass*>::iterator itr = m_elements.begin(), end = m_elements.end(); itr != end; ++itr){
  // ループの中身
}
  • 行が長くなって読みづらい

1つの行に1つのstatement

for(std::vector<MyClass*>::iterator itr = m_elements.begin(),
                                    end = m_elements.end();
                                    itr != end;
                                    ++itr){
  // ループの中身
}
  • 初期化部分だけ2行あって、終了条件部分、更新部分との対称性が悪い

行の長さだけを基準に改行

for(std::vector<MyClass*>::iterator itr = m_elements.begin(),
    end = m_elements.end(); itr != end; ++itr){
  // ループの中身
}
  • 意味と表記がちぐはぐで読みづらい

上2つをハイブリッドした感じ

for(std::vector<MyClass*>::iterator itr = m_elements.begin(),
                                    end = m_elements.end();
                                    itr != end; ++itr){
  // ループの中身
}
  • 3行目に終了条件と更新部分が押し込まれていてちょっと読みづらいかな…?

イテレータの型をtypedefして短くする

typedef std::vector<MyClass*>::iterator vi;
for(vi itr = m_elements.begin(), end = m_elements.end(); itr != end; ++itr){
  // ループの中身
}
  • 局所的なtypedefって、コードを読むときに脳内メモリに載せないといけない情報が動的に増減するからあんま好きじゃない
  • んだけどこれは慣れなかなぁ

どれも微妙なところがあってこれだというのが決められませんが、今のところ4つめの「ハイブリッドした感じ」を使っています。


「というかイテレータのループじゃなくてalgorithm使えよ」という話もありますが、なかなかそう綺麗に置き換えられる場合ばかりではなくて。複雑なファンクタ作って無理にalgorithm使うようにしても、それはそれで保守性悪くなってしまうでしょう(僕がまだSTLをマスターしていないから上手く書けないというだけかもしれませんが…)。