STL迭代器是否保证集合更改后的有效性?

发布于 2024-09-11 11:34:44 字数 205 浏览 4 评论 0原文

假设我有某种集合,并且我在它的开头获得了一个迭代器。现在假设我修改了该集合。无论集合或迭代器的类型如何,我仍然可以安全地使用迭代器吗?

为了避免混淆,这里是我讨论的操作顺序:

  1. 获取集合的迭代器。
  2. 修改集合(显然 不是其中的元素,而是集合本身)。
  3. 使用步骤1中获得的迭代器。根据STL标准它仍然有效吗?!

Let's say I have some kind of collection and I obtained an iterator for the beginning of it. Now let's say I modified the collection. Can I still use the iterator safely, regardless of the type of the collection or the iterator?

To avoid confusion, here is the order of operations I talk about:

  1. Get an iterator of the collection.
  2. Modify the collection (obviously
    not an element in it, but the collection itself).
  3. Use the iterator obtained at step 1. Is it stil valid according to STL standard?!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

慕巷 2024-09-18 11:34:44

取决于容器。例如,如果它是一个向量,则修改容器后,所有迭代器都会失效。但是,如果它是一个列表,则与修改位置无关的迭代器将保持有效。

  • 当向量的内存被重新分配时,它的迭代器就会失效。此外,在向量中间插入或删除元素会使指向插入或删除点之后的元素的所有迭代器无效。因此,如果使用 reserve() 预分配向量将使用的内存,并且所有插入和删除都位于向量的末尾,则可以防止向量的迭代器失效。 [1]

  • deque 的迭代器失效语义如下。 Insert(包括push_frontpush_back)会使所有引用deque的迭代器失效。 deque 中间的 Erase 会使引用该 deque 的所有迭代器无效。 deque 开头或结尾处的 Erase(包括 pop_frontpop_back)仅在迭代器指向时使迭代器无效到被擦除的元素。 [2]

  • List有一个重要的属性,即插入和拼接不会使列表元素的迭代器无效,并且即使删除也只会使指向被删除元素的迭代器无效。 [3]

  • Map 有一个重要的属性,即向 map 中插入新元素不会使指向现有元素的迭代器失效。从映射中删除元素也不会使任何迭代器无效,当然,实际指向正在删除的元素的迭代器除外。 [4]set 相同,multisetmultimap)

Depends on the container. e.g. if it's a vector, after modifying the container all iterators can be invalidated. However, if it's a list, the iterators irrelevant to the modified place will remain valid.

  • A vector's iterators are invalidated when its memory is reallocated. Additionally, inserting or deleting an element in the middle of a vector invalidates all iterators that point to elements following the insertion or deletion point. It follows that you can prevent a vector's iterators from being invalidated if you use reserve() to preallocate as much memory as the vector will ever use, and if all insertions and deletions are at the vector's end. [1]

  • The semantics of iterator invalidation for deque is as follows. Insert (including push_front and push_back) invalidates all iterators that refer to a deque. Erase in the middle of a deque invalidates all iterators that refer to the deque. Erase at the beginning or end of a deque (including pop_front and pop_back) invalidates an iterator only if it points to the erased element. [2]

  • Lists have the important property that insertion and splicing do not invalidate iterators to list elements, and that even removal invalidates only the iterators that point to the elements that are removed. [3]

  • Map has the important property that inserting a new element into a map does not invalidate iterators that point to existing elements. Erasing an element from a map also does not invalidate any iterators, except, of course, for iterators that actually point to the element that is being erased. [4] (same for set, multiset and multimap)

终遇你 2024-09-18 11:34:44

这取决于相关的收藏。例如,修改 std::vector(例如,在某处添加元素)可能会使该向量中的所有迭代器无效。相比之下,对于 std::list,当您向列表添加另一个元素时,迭代器仍然有效。在某些情况下,规则甚至更复杂(例如,如果内存可用,使用 std::deque,添加到开头或结尾会使现有迭代器有效,但添加到其他任何地方可能会使它们无效 - - 但我的记忆力很差,你应该在这之前检查一下)。

That depends on the collection in question. Just for example, modifying a std::vector (e.g., adding an element somewhere) can invalidate all iterators into that vector. By contrast, with a std::list, iterators remain valid when you add another element to the list. In some cases, the rules are even more complex (e.g., if memory serves, with a std::deque, adding to the beginning or end leaves existing iterators valid, but adding anywhere else can invalidate them -- but my memory is sufficiently poor that you should check before depending on that).

烟酉 2024-09-18 11:34:44

不,只有当被迭代的容器不变时,迭代器才有效。如果集合被修改,则应重新获取迭代器。

No, iterators are only good while the iterated container is unchanged. If a collection is modified, the iterator should be obtained anew.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文