对deque中的迭代器失效感到困惑
我对有关迭代器无效的问题感到困惑。 (在这个问题的背景下)
以下是由Nicolai M. Josuttis撰写的“C ++标准库:教程和参考”摘录
任何插入或删除除开头或结尾之外的元素均会使所有指向双端队列元素的指针,引用和迭代器无效。
以下是SGI网站的摘录:
iteque失效的语义如下。 插入(包括push_front
和push_back
)会使所有引用deque的迭代器失效。 在deque中间擦除将导致所有引用deque的迭代器失效。 擦除在deque的开始或结束处(包括pop_front
和pop_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”的人之一,这已经导致你的困惑。
以下是由Nicolai M. Josuttis撰写的“C ++标准库:教程和参考”摘录
任何插入或删除除开头或结尾之外的元素均会使所有指向双端队列元素的指针,引用和迭代器无效。
简而言之,Josuttis的这段话是误导性的,暗示插入或删除开始或结尾的元素不会使指针,引用或迭代器无效......但值得注意的是,他从不出来并直接声明这一点。
以下是std::deque
的真实,正确的官方规则:
C ++ 03
插入 :所有迭代器和引用都是无效的,除非插入的成员位于deque的末端(前或后)(在这种情况下,所有迭代器都是无效的,但对元素的引用不受影响)[23.2.1.3/1]
擦除(Erasure) :除非被擦除的成员在deque的末端(前面或后面)(在这种情况下,只有迭代器和对被擦除成员的引用无效),否则所有迭代器和引用都将失效。[23.2.1.3/4]
调整大小 :按照插入/擦除[23.2.1.2/1]
C ++ 11
插入 :所有迭代器和引用都是无效的,除非插入的成员位于deque的末端(前面或后面)(在这种情况下,所有迭代器都是无效的,但对元素的引用不受影响)[23.3.3.4/1]
擦除 :擦除最后一个元素只会使迭代器和对已擦除元素和过去末端迭代器的引用无效; 擦除第一个元素只会使迭代器和对擦除元素的引用无效; 擦除任何其他元素使所有迭代器和引用无效(包括过去末端迭代器)[23.3.3.4/4]
调整大小 :按照插入/擦除[23.3.3.4/1]
进一步阅读
我不确定什么进一步提及了你正在寻找的可靠来源 - 相关标准段落已经被引用和引用。
SGI实现可能使用可增长的数组,所以如果插入导致数组增长,则指向旧数组的迭代器将无效。
编辑:
在C ++编程语言第三版的第17.2.3节中,我没有在deque的描述中看到任何指示什么操作保存或使迭代器无效的内容。 我可能在错误的位置查看,或者行为可能未定义。
链接地址: http://www.djcxy.com/p/73319.html