2009-11-02 78 views
7

剛纔,我正在閱讀Josuttis的STL書籍。C++ deque的迭代器在push_front()之後失效

據我所知 - C++ vector是一個可以重新分配的c數組。所以,我明白,爲什麼在push_back()之後所有迭代器和引用都可能失效。

但我的問題是關於std :: deque。據我所知它是一個大塊數組(c數組的c數組)。因此,push_front()在開始處插入元素,如果沒有空間,則deque分配新塊,並將該元素放置在分配塊的末尾。

在插入()中間所有引用和迭代器變得無效後,我明白爲什麼 - 所有元素都被移動。 但是我真的誤解了「...... push_back()和push_front()後所有引用保持有效,但迭代器不能」(相同的短語可以在@ standard:23.2.2.3找到)

它是什麼意思?!如果引用有效,則deque無法重新分配(==移動)其元素。那麼迭代器爲什麼會失效?爲什麼不能在非移動元素插入後使用它們?或者這個短語是否意味着我無法確定迭代器是否等於開始()或結束()和溢出?另外,我想提一下,在erase()之後,所有迭代器和引用都保持有效(除了已擦除的:-))。 PS:請不要以「標準」形式回答:「不能使用,因爲標準如此說明」。 我想明白爲什麼,會發生什麼。

回答

7

我認爲迭代器失效的原因,但不引用可能是因爲指向存儲元素的deque頁面的指針數組的可能deque實現。對deque中元素的引用將直接引用「頁面」中的元素。然而,進入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

也許你是對的。 但迭代器應該如何實現,在插入新頁面後變爲無效。或者他們可能會有字段「頁數」變得不正確? – f0b0s 2009-11-02 10:10:31

+1

我想迭代器會有兩個字段:其中一個是指向左側的「指針數組」的指針,另一個是指向右側相應的「數據頁」的指針或偏移量。因此,增量將實現爲(1)在數據頁面中增加位置,(2)如果到達頁面末尾,則增加主索引中的位置並將數據頁面位置重置爲下一頁的開始。因此,如果主索引被重新分配,迭代器將變爲無效。 – 2009-11-02 11:52:35

+0

@oebyone耶!很好的答案,你是對的!感謝名單。 – f0b0s 2009-11-02 14:23:13