簡體   English   中英

在deque中對迭代器失效的困惑

[英]Confusion on iterators invalidation in deque

關於deque中的迭代器失效,我有點困惑。 (在這個問題的背景下)

以下是摘自 - The C ++標准庫:教程和參考,作者:Nicolai M. Josuttis

開頭或結尾之外的任何元素的插入或刪除都會使引用雙端隊列元素的所有指針,引用和迭代器無效。

以下是SGI網站的摘錄:

deque的迭代器失效的語義如下。 Insert(包括push_frontpush_back )使引用deque的所有迭代器無效。 在雙端隊列中間擦除使所有引用雙端隊列的迭代器無效。 在雙端隊列的開頭或結尾處擦除(包括pop_frontpop_back )只有在指向已擦除元素時才會使迭代器無效。

恕我直言,deque是塊的集合,第一個塊在一個方向上生長,最后一個塊在相反方向上生長。

  -   -  -  
  -   -  -
  |   -  -  ^
  |   -  -  |
  V   -  -  |
      -  -  -
      -  -  -

push_back, push_front不應該對deque迭代器產生任何影響(我同意Josuttis)。

什么是正確的解釋? 標准對此有何看法?

標准的工作草案

template <class InputIterator> void insert(iterator position,InputIterator first,InputIterator last);

1效果:deque中間的插入使所有迭代器和對deque元素的引用無效。 在deque兩端的插入使deque的所有迭代器無效,但對deque元素的引用的有效性沒有影響。“

所以兩者都是正確的。 正如Josuttis指出的那樣,在前面或后面插入並不會使對deque元素的引用無效,只會對deque本身進行迭代。

編輯: 更新的草案基本上是相同的(第23.2.2.3節)

恕我直言,deque是塊的集合,第一個塊在一個方向上生長,最后一個塊在相反方向上生長。

你的意見是你的特權,但這是錯的。 :)

deque語義上是這樣的容器,但在實現方面,它被設計為由一個或多個內存塊實現。 C ++的迭代器失效規則來自實現,所以這就是原因。 可以說這是一個小的抽象泄漏,但是,無論如何。

SGI STL文檔不是正確的文檔,因為SGI STL不是C ++標准庫 不幸的是,Josuttis是那些稱之為“STL”的人之一,這導致了你的困惑。


以下是摘自 - The C ++標准庫:教程和參考,作者:Nicolai M. Josuttis

開頭或結尾之外的任何元素的插入或刪除都會使引用雙端隊列元素的所有指針,引用和迭代器無效。

簡單地說,從約祖蒂斯這段話在暗示被誤導認為在開頭或結尾, 壞指針,引用或迭代器......雖然這是值得注意的是,他從來沒有出來,並聲稱這完全元素的插入或刪除。


以下是std::deque的真實,正確的官方規則:

C ++ 03

  • 插入 :所有迭代器和引用都是無效的,除非插入的成員位於雙端隊列的末尾(前面或后面)(在這種情況下,所有迭代器都無效,但對元素的引用不受影響)[23.2.1.3/1]

  • 擦除 :所有迭代器和引用都無效,除非擦除的成員位於雙端隊列的末尾(前面或后面)(在這種情況下,只有迭代器和對擦除成員的引用無效)[23.2.1.3/4]

  • 調整大小 :按插入/刪除[23.2.1.2/1]

C ++ 11

  • 插入 :所有迭代器和引用都是無效的,除非插入的成員位於雙端隊列的末尾(前面或后面)(在這種情況下,所有迭代器都無效,但對元素的引用不受影響)[23.3.3.4/1]

  • 擦除 :擦除最后一個元素只會使迭代器和對擦除元素的引用以及過去的迭代器無效; 擦除第一個元素只會使迭代器和對擦除元素的引用無效; 擦除任何其他元素會使所有迭代器和引用無效(包括過去的迭代器)[23.3.3.4/4]

  • 調整大小 :按插入/刪除[23.3.3.4/1]


進一步閱讀

我不確定你還在尋找可靠來源的進一步參考 - 相關的標准段落已被引用和引用。

SGI實現可能使用可增長的數組,因此如果插入導致數組增長,則指向舊數組的迭代器無效。

編輯:

查看C ++編程語言第三版的第17.2.3節,我在deque的描述中沒有看到任何表明操作保留或使迭代器無效的內容。 我可能正在尋找錯誤的位置或行為可能未定義。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM