2009-11-02 10 views
7

ちょうど今、私はJosuttisのSTLの本を読んでいます。push_front()の後にC++ dequeのイテレータが無効にされる

私が知る限り、C++ vectorは再配置可能なc配列です。ですから、push_back()の後にすべてのイテレータと参照が無効になる理由を理解しています。

しかし、私の質問はstd :: dequeです。私が知っているように、それは大きなブロック(c配列のc配列)の配列です。したがって、push_front()は最初に要素を挿入し、空白がない場合、dequeは新しいブロックを割り当て、割り当てられたブロックの最後に要素を置きます。

途中でinsert()を実行すると、すべての参照とイテレータが無効になり、すべての要素が移動される理由がわかります。 しかし、私は本当に "... push_back()とpush_front()の後もすべての参照は有効ですが、イテレータはありません"というフレーズを誤解しています。(同じフレーズは23.2.2.3で見つけることができます)

平均?!参照が有効な場合、dequeはその要素を再割り当て(==移動)できませんでした。なぜイテレータが無効になるのですか?移動していない要素の挿入後に使用できないのはなぜですか?あるいは、そのフレーズは、イテレータの開始()または終了()とオーバーフローについての平等については確信できません。

また、私はerase()の後にすべてのイテレータとリファレンスが有効なままであることを言いたいと思います(消去されたものを除いて:-))。

PS:「標準」形式では答えないでください:「標準がそう言っているので使用できません」 私はなぜ、何が起こるのか理解したい。

答えて

7

イテレータが無効になる理由は、要素を格納する両端キューのページへのポインタ配列のdeque実装の可能性があるためです。両端キュー内の要素への参照は、「ページ」内の要素を直接参照します。ただし、両端キューへのイテレータは、さまざまなページを指すポインタのベクトルに依存している可能性があります。

新しい要素を一方または他方の端で両端キューに挿入すると、exstingデータページを再割り当ておよび移動する必要はありませんが、ページポインタの配列に追加する必要があります(したがって&をコピーする必要があります)以前のページポインターの配列に置き換えます。

Array of pointers   
(if this grows     Data Pages 
and gets copied,   (these never move 
iterators are invalid)  due to insert at ends) 
-----------------   -------------------- 

+----------+    +----------+ 
|   -+-------------->|   | 
+----------+    +----------+ 
|   -+---------+  |   | 
+----------+   |  +----------+ 
|   -+---+  |  |   | 
+----------+ |  |  +----------+ 
       |  | 
       |  | 
       |  | 
       |  |  +----------+ 
       |  +---->|   | 
       |   +----------+ 
       |   |   | 
       |   +----------+ 
       |   |   | 
       |   +----------+ 
       |   
       |   +----------+ 
       +---------->|   | 
          +----------+ 
          |   | 
          +----------+ 
          |   | 
          +----------+ 
+0

が適切かもしれません。 しかし、イテレータをどのように実装して新しいページを挿入した後に無効にするか。フィールド「num of pages」が不正確になることがありますか? – f0b0s

+1

イテレータには2つのフィールドがあります。そのうちの1つは左側の「ポインタの配列」へのポインタで、もう1つは右側の対応する「データページ」へのポインタまたはオフセットです。インクリメントは、(1)データページの位置をインクリメントする、(2)ページの最後に達した場合、マスタインデックスの位置をインクリメントし、データページの位置を次のページの先頭にリセットする。したがって、マスタインデックスが再割り当てされると、イテレータは無効になります。 –

+0

@oebyone yeah!素晴らしい答え、あなたは正しいです!高すぎる。 – f0b0s

関連する問題