すでによく答えられていますが、S/0.02を追加します。これを行う「正しい」方法は次のとおりです。
for (typename std::vector<MyObject>::size_type i = 0; i < object.size(); ++i) { ... }
意欲的な言語弁護士だけがそれを書くでしょう、そして彼らでさえ彼らが良いものに到達する前に読むのをやめるでしょう。
C ++ 11を使用すると、次の利点を活用できますdecltype
。
for (decltype(object.size()) i = 0; i < object.size(); ++i) { ... }
または、以下を利用できますauto
。
for (auto i = object.size() - object.size(); i < object.size(); ++i) { ... }
または、を使用することもできますが、のsize_typeがsize_tよりも大きい可能性があるsize_t
ため、オーバーフローについて疑問がある場合があります。vector<MyObject>
(そうではありませんが、保証はありません):
for (size_t i = 0; i < object.size(); ++i) { ... }
では、正直なプログラマーは何をするのでしょうか?
絶対に簡単な解決策は、STLが最初から推進してきた解決策です。それを除いて、最初は書くのも苦痛でした:
for (typename std::vector<MyObject>::iterator_type it = object.begin(); it != object.end(); ++it) { ... }
さて、C++11は実際にあなたを助けます。単純なものから始めて、いくつかの非常に優れた選択肢があります。
for (auto it = object.begin(); it != object.end(); ++it) { ... }
しかし、それはさらに良くなります(ドラムロールをお願いします)...:
for (auto& val : object) { ... }
そして、それは私が使用するものです。
追加するために編集:
Cory Nelsonはコメントの中で、object.end()の結果を次のようにキャッシュすることも可能であると指摘しています。
for (auto it = object.begin(), end = object.end(); it != end; ++it) { ... }
構文によって生成されたコードは、for (var : object)
CoryNelsonによって提案されたものと非常に似ていることがわかります。(だから私は彼とあなたに後者を使うことを勧めます。)
ただし、元の投稿の主題であった反復を含め、他のセマンティクスとは微妙に異なるセマンティクスがあります。反復中にコンテナのサイズを変更するように変更する場合は、慎重に検討する必要があります。災害の可能性が高いです。
反復中に変更される可能性のあるベクトルを反復する唯一の方法は、元の投稿のように整数インデックスを使用することです。他のコンテナはより寛容です。反復ごとにobject.end()を呼び出すループを使用してSTLマップを反復できます。(私が知る限り)挿入や削除を行っても機能しますが、unordered_mapでは試さないでください。またはベクトル。常に最後を押して前をポップする場合は、両端キューで機能します。これは、幅優先探索で両端キューをキューとして使用する場合に便利です。後ろの両端キューをポップすることで逃げることができるかどうかはわかりません。
これはすべて標準で指定されているため、イテレーターと要素ポインター(イテレーターと常に同じとは限りません)に対するコンテナータイプのコンテナー変更による影響の簡単な要約が実際にどこかにあるはずですが、私はそれに遭遇したことはありませんどこでも。見つけたら教えてください。