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

C++ STL迭代器是否保证集合更改后的有效性?,c++,stl,iterator,containers,C++,Stl,Iterator,Containers,假设我有一个集合,在它的开头我得到了一个迭代器。现在让我们假设我修改了集合。无论集合或迭代器的类型如何,我仍然可以安全地使用迭代器吗 为了避免混淆,以下是我谈论的操作顺序: 获取集合的迭代器 修改集合(显然是 不是其中的元素,而是集合本身) 使用在步骤1中获得的迭代器。根据STL标准它仍然有效吗 不,迭代器只有在迭代器容器保持不变时才有效。如果修改了集合,则应重新获取迭代器。取决于容器。e、 g.如果是向量,修改容器后,所有迭代器都可能失效。但是,如果它是一个列表,则与修改位置无关的迭代器将保持

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

为了避免混淆,以下是我谈论的操作顺序:

  • 获取集合的迭代器
  • 修改集合(显然是 不是其中的元素,而是集合本身)
  • 使用在步骤1中获得的迭代器。根据STL标准它仍然有效吗
    不,迭代器只有在迭代器容器保持不变时才有效。如果修改了集合,则应重新获取迭代器。

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

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

    • deque
      的迭代器无效语义如下所示
      Insert
      (包括
      push_front
      push_back
      )使引用
      deque
      的所有迭代器无效<代码>擦除<代码> >在代码< > DeQue>代码>使所有引用“代码> DEQU</代码>的迭代器无效。在
      deque
      的开头或结尾处的code>Erase(包括
      pop\u front
      pop\u back
      )仅当迭代器指向已擦除的元素时,迭代器才会失效

    • List
      s有一个重要的特性,即插入和拼接不会使列表元素的迭代器失效,即使删除也只会使指向已删除元素的迭代器失效

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


    这取决于所讨论的收藏品。例如,修改一个
    std::vector
    (例如,在某处添加一个元素)会使该向量中的所有迭代器无效。相比之下,对于
    std::list
    ,当您向列表中添加另一个元素时,迭代器仍然有效。在某些情况下,规则甚至更为复杂(例如,如果内存可用,使用
    std::deque
    ,则添加到开头或结尾会使现有迭代器有效,但添加到任何其他位置都可能使迭代器无效,但我的内存足够差,您应该在删除列表元素之前进行检查)。

    如果删除列表元素会怎么样?如果它是迭代器指向的元素呢?删除迭代器引用的元素会使迭代器无效。擦除任何其他元素都不会。换句话说,如果修改列表,在某些情况下它将使迭代器无效(指向已擦除的元素),因此迭代器的有效性不保证-正确?但是,
    vector::insert
    (单个元素)和
    vector::erase
    ,返回一个新的有效,迭代器。肯尼:根据标准,你说的是真的还是真的,因为这是stl通常的实现方式?你能修改你的答案,让它也解释一下吗?谢谢。@yossi1981:这是由标准定义的。标准中非常明确地定义了迭代器失效的条件。感谢大家的快速响应。严格来说,这不是真的(示例列表不遵循这些规则)。问题是“无论集合(容器)的类型如何”。无论问题是什么,你在回答中所作的陈述具有误导性,因为它在某些情况下是正确的,而在(许多)其他情况下是错误的。