0

std::insert_iteratorそのコンテナを参照する C++ を無効にする STL コンテナへのアクションは何ですか? insert_iterator基礎となるイテレーター (保護されたメンバーiter) が通常のイテレーターの無効化規則に従っている場合、は有効ですか?

関連: std::insert_iterator と iterator の無効化は、無効の例を示していますinsert_iteratorが、ルールを解明していません。

4

2 に答える 2

2

基になる反復子 (保護されたメンバー反復子) が次の場合、insert_iterator は有効ですか?

正解です。これが、保護されたメンバーが仕様に記載されており、insert_iterator(具体的にoperator=は、残りはノーオペレーションであるため) で動作する関数が、アクセスする関数の観点から定義されている理由です。iter

于 2012-07-04T22:13:18.967 に答える
1

ええと、答えは具体的に何について尋ねているかによって異なります。

(これを邪魔にならないようにするために、「関連」リンクは完全に無関係であることにすぐに注意したいと思います。そのリンクのコードの問題は、insert_iterator無効化とはまったく関係ありません。その質問の作成者は問題を誤解しましたそして、実際の問題は解決しないまま、存在しない問題を解決しようとすることになりました. 私はその質問にも追加の回答を提供しました.)

insert_iterator ins有効なイテレータからを作成してからcontainer::iterator it、コンテナに対して無効化する何かを個別に行うとitinsも無効化されます。これは当然のことです。ins単独でコンテナに何かが起こったことを知る方法はありません。

insert_iteratorただし、挿入時に自己修復する性質も同時に持っています。たとえば、 を使用insert_iterator insして にデータを挿入するとvectorinsベクトルが再割り当てされても有効なままになります。つまり、ベクトルの再割り当ては大規模な反復子無効化イベントですが、損傷はありませんins(もちろん、再割り当てが を介して実行された挿入によってトリガーされたと仮定しますins)。

これは、標準の挿入アルゴリズムに従います。

it = container->insert(it, value);
++it;

whereitは、内部に格納されている基になる挿入ポイント イテレータinsert_iteratorです。前挿入イテレータと後挿入イテレータには、同じ「自己修復」プロパティもあります。潜在的に無効な内部反復子は、すぐに再検証されます。

違いを説明するために、次の簡単な例を考えてみましょう

std::vector<int> v(10);
std::vector<int>::iterator it = v.begin() + 5;

for (unsigned n = 20; n > 0; --n)
  v.insert(it, rand());

このコードは一般に無効です。挿入サイクル中にコンテナーが再割り当てされる可能性が非常に高く、それ以降のitすべての挿入が無効になり、無効になるからです。

同時にこのコード

std::vector<int> v(10);
std::vector<int>::iterator it = v.begin() + 5;
std::insert_iterator<std::vector<int> > it_ins(v, it);

for (unsigned n = 20; n > 0; --n)
  *it_ins++ = rand();

ベクトルが再割り当てされるかどうかに関係なく、正常に動作することが保証されています。

于 2012-07-04T22:38:40.233 に答える