C ++
 Computer >> コンピューター >  >> プログラミング >> C ++

C++でのイテレータの無効化


C ++には、vector、list、set、mapなどのさまざまなコンテナーがあります。これらのコンテナーを反復処理するには、反復子を使用できます。 C ++でイテレータを使用する場合は注意が必要です。コンテナでイテレータを使用する場合、無効になることがあります。形や大きさを変えると、こういう問題に直面することがあります。次の例では、無効化の問題を特定できます。

サンプルコード

#include <iostream>
#include <vector>
using namespace std;
int main() {
   vector <int> vec{11, 55, 110, 155, 220};
   for (auto it=vec.begin(); it!=vec.end(); it++)
      if ((*it) == 110)
         vec.push_back(89); //inserting a new value while iterating the vector
      for (auto it=vec.begin();it!=vec.end();it++)
         cout << (*it) << " ";
}
のベクトルを反復しながら新しい値を挿入します

出力

11 55 110 155 220 89 89

このプログラムでは、さまざまな種類の結果を得ることができます。ここでは、ベクトルのサイズは以前に定義されていません。初期化のためにいくつかの値が提供されています。繰り返しながら、もう1つの価値を追加しています。この場合、ベクターにスペースがない場合、実行時に新しいメモリブロックが作成され、すべてのアイテムがコピーされます。ただし、イテレータは前のアドレスを指します。このため、いくつかの無効化が発生する可能性があります。

イテレータの無効化に関するいくつかのルールを見てみましょう。


挿入
消去
サイズ変更
ベクター
挿入ポイントの前の要素を指しているすべてのイテレータは影響を受けませんが、他のイテレータは無効になります。また、ベクトルのサイズを大きくすると、すべてのイテレータが無効になります。
削除ポイントの後にあるすべてのイテレータと参照が無効になります。
挿入または消去と同じです。
Deque
挿入されたアイテムが両端キューの最後に挿入されていない場合、すべてのイテレータと参照は無効になります。
終了位置以外のいずれかの位置からアイテムが削除されると、すべてのイテレータが無効になります。
挿入または消去と同じです。
リスト
すべてのイテレータと参照は影響を受けません
消去される要素を指しているイテレータまたは参照のみが影響を受けます。
挿入または消去と同じです。
セット、マップ、マルチセット、マルチマップ
すべてのイテレータと参照は影響を受けません
消去される要素を指しているイテレータまたは参照のみが影響を受けます。
----

  1. C++の二分探索木イテレータ

    二分木用に1つのイテレータを作成するとします。 2つの方法があります。 next()メソッドは次の要素を返し、hasNext()メソッドはブール値を返します。これは次の要素が存在するかどうかを示します。したがって、ツリーが次のような場合- そして、関数呼び出しのシーケンスは、[next()、next()、hasNext()、next()、hasNext()、next()、hasNext()、next()、hasNext()]です。出力は[3,7、true、9、true、15、true、20、false]になります これを解決するには、次の手順に従います- nextとhasNextの

  2. C#のイテレータ

    イテレータは、コレクションに対してカスタム反復を実行します。これは、yield returnステートメントを使用して、各要素を一度に1つずつ返します。イテレータは現在の場所を記憶し、次の反復で次の要素が返されます。 以下は例です- 例 using System; using System.Collections.Generic; using System.Linq; namespace Demo {    class Program {       public static IEnumerable<string> displa