[英]Confusion on iterators invalidation in deque
关于deque中的迭代器失效,我有点困惑。 (在这个问题的背景下)
以下是摘自 - The C ++标准库:教程和参考,作者:Nicolai M. Josuttis
除开头或结尾之外的任何元素的插入或删除都会使引用双端队列元素的所有指针,引用和迭代器无效。
以下是SGI网站的摘录:
deque的迭代器失效的语义如下。 Insert(包括
push_front
和push_back
)使引用deque的所有迭代器无效。 在双端队列中间擦除使所有引用双端队列的迭代器无效。 在双端队列的开头或结尾处擦除(包括pop_front
和pop_back
)只有在指向已擦除元素时才会使迭代器无效。
恕我直言,deque是块的集合,第一个块在一个方向上生长,最后一个块在相反方向上生长。
- - -
- - -
| - - ^
| - - |
V - - |
- - -
- - -
push_back, push_front
不应该对deque迭代器产生任何影响(我同意Josuttis)。
什么是正确的解释? 标准对此有何看法?
恕我直言,deque是块的集合,第一个块在一个方向上生长,最后一个块在相反方向上生长。
你的意见是你的特权,但这是错的。 :)
deque
在语义上是这样的容器,但在实现方面,它被设计为由一个或多个内存块实现。 C ++的迭代器失效规则来自实现,所以这就是原因。 可以说这是一个小的抽象泄漏,但是,无论如何。
SGI STL文档不是正确的文档,因为SGI STL不是C ++标准库 。 不幸的是,Josuttis是那些称之为“STL”的人之一,这导致了你的困惑。
以下是摘自 - The C ++标准库:教程和参考,作者:Nicolai M. Josuttis
除开头或结尾之外的任何元素的插入或删除都会使引用双端队列元素的所有指针,引用和迭代器无效。
简单地说,从约祖蒂斯这段话在暗示被误导认为是在开头或结尾, 不坏指针,引用或迭代器......虽然这是值得注意的是,他从来没有出来,并声称这完全元素的插入或删除。
以下是std::deque
的真实,正确的官方规则:
插入 :所有迭代器和引用都是无效的,除非插入的成员位于双端队列的末尾(前面或后面)(在这种情况下,所有迭代器都无效,但对元素的引用不受影响)[23.2.1.3/1]
擦除 :所有迭代器和引用都无效,除非擦除的成员位于双端队列的末尾(前面或后面)(在这种情况下,只有迭代器和对擦除成员的引用无效)[23.2.1.3/4]
调整大小 :按插入/删除[23.2.1.2/1]
插入 :所有迭代器和引用都是无效的,除非插入的成员位于双端队列的末尾(前面或后面)(在这种情况下,所有迭代器都无效,但对元素的引用不受影响)[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.