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

use*_*637 30 c++ containers iterator stl

假设我有一些集合,我在它的开头就获得了一个迭代器.现在让我们说我修改了这个集合.无论集合的类型还是迭代器,我还能安全地使用迭代器吗?

为避免混淆,这是我谈到的操作顺序:

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

ken*_*ytm 44

取决于容器.例如,如果它是a vector,则在修改容器之后,所有迭代器都可以无效.但是,如果它是a list,则与修改后的位置无关的迭代器将保持有效.

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

  • 迭代器失效的语义deque如下.Insert(包括push_frontpush_back)使引用a的所有迭代器无效deque.Erase在中间deque使所有引用的迭代器无效deque.Erasedeque(包括pop_frontpop_back)的开头或结尾处,只有当迭代器指向已擦除的元素时才会使其失效.[2]

  • Lists具有重要的属性,即插入和拼接不会使列表元素的迭代器无效,甚至删除也只会使指向被删除元素的迭代器无效.[3]

  • Map具有重要的属性,即将新元素插入到一个map不会使指向现有元素的迭代器失效.从地图中删除元素也不会使任何迭代器无效,当然,除了实际指向正在被删除的元素的迭代器之外.[4](同样的set,multisetmultimap)

  • @ yossi1981:这是由标准定义的.在标准中非常明确地定义了迭代器失效的条件. (8认同)

Jer*_*fin 8

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

  • 怎么擦除列表元素怎么办?如果它是迭代器指向的元素怎么办? (2认同)