当前位置: 首页 > 知识库问答 >
问题:

C 11中的结束迭代器无效

阎渝
2023-03-14

最受欢迎的C迭代器失效规则帖子声称,不清楚过去的结束迭代器(即,end()cend()rend()、和crend())是否根据与普通迭代器相同的规则失效,这些迭代器指向容器中的元素。这些针对2003年和2011年C版的声明都遵从了一篇讨论结束迭代器失效规则的帖子,其中公认的答案表明2003年的标准在这个问题上是模糊的。这一结论基于23.1/10(在swap()的上下文中)中的一条评论,该评论似乎暗示,当规范没有明确提到结束迭代器失效时,它们可能会失效。

关于那篇帖子的问题(由迈克·西摩(mike seymour)发表的评论表明,C 11在这个问题上是明确的,在deques的情况下。我的问题是关于所有容器:

  • 在C 11中,是否有任何容器操作会使过去的迭代器失效,以及这种行为在语言规范中是不明确的

换言之,

  • 执行了一个容器操作(该操作不会使过去的结束迭代器无效)之后,我能相信过去的结束迭代器的有效性吗

共有3个答案

慕阳
2023-03-14

至少在GCC结束迭代器得到无效的std::地图:

#include <set>
#include <stdlib.h>
#include <assert.h>
int main() {
  std::set<int> a;
  a.insert(1);
  std::set<int>::reverse_iterator rit(a.rbegin());
  ++rit;
  assert(rit==a.rend());
  a.erase(a.begin());
  assert(a.rend()==rit); // FAIL
}
曹茂材
2023-03-14

如果标准说该操作不会使迭代器失效,那么您应该能够信任它。在标准库实现中,任何其他内容都应该被视为bug。

萧安怡
2023-03-14

我的问题是关于所有容器:

  • 在C 11中,是否有任何容器操作可能会使过去的迭代器无效,并且在语言规范中这种行为是模糊的?

我不确定你所说的“语言规范中这种行为是模糊的”是什么意思,但是肯定有一些操作会使过去的操作符无效(比如插入到std::向量std::字符串)。

换言之,

  • 在执行了一个容器操作(该操作不会使过去的结束迭代器无效)之后,我能相信过去的结束迭代器的有效性吗

您可以像信任任何其他迭代器一样信任结束迭代器:任何不会(潜在地)使迭代器无效的操作都不会使迭代器无效。除了标准中可能存在的bug之外,这是所有操作中都没有说它们(可能)使操作符无效的情况。

 类似资料:
  • 我正在使用数组实现一个向量数据结构。自然,向量类对数据数组、其容量和大小有私有变量。 我想要一个迭代器作为内部类。迭代器被实现为一个简单的int。运算符必须检查它是否已到达数组的末尾。它是怎么做到的?如果数据结构是一个链表,那么只需检查指向下一个节点的指针==NULL。 我想到了两种解决方案,列表中的sentinel对象或指向数组大小的指针,作为迭代器内部类的私有变量。这两种解决方案似乎都不令人满

  • 本文向大家介绍C ++程序中的迭代器无效,包括了C ++程序中的迭代器无效的使用技巧和注意事项,需要的朋友参考一下 在本教程中,我们将讨论一个程序,以了解C ++中的迭代器失效。 在容器对象的元素上进行迭代时,有时如果我们不应用绑定检查,它可能会失效。这主要是由于容器对象的形状和大小的变化而发生的。 示例 输出结果 (可能还会发生,添加新元素时,矢量将被复制到新位置,而我们的迭代器仍指向旧位置,这

  • 本文向大家介绍总结javascript中的六种迭代器,包括了总结javascript中的六种迭代器的使用技巧和注意事项,需要的朋友参考一下 1.forEach迭代器 forEach方法接收一个函数作为参数,对数组中每个元素使用这个函数,只调用这个函数,数组本身没有任何变化 在浏览器中输出的结果是: 2.every迭代器 every方法接受一个返回值为布尔类型的函数,对数组中的每个元素使用这个函数,

  • 问题内容: 什么是迭代器和集合?这两个有关系吗? 接口迭代器是否只预定义了这些方法名称,还是用户定义了这些方法名称?下面的这四行实际上说明了什么? 谢谢。我正在看一本藏书。 问题答案: 顾名思义,Java集合是事物的集合。如果您不知道该单词,请在字典中查找。 有很多类型的集合。以集合的数学概念为例。您可以将任意事物放入集合中,但是永远不会包含同一事物。在集中的东西是没有顺序的,那就是你不能说 A

  • 本文向大家介绍C ++中的RLE迭代器,包括了C ++中的RLE迭代器的使用技巧和注意事项,需要的朋友参考一下 假设我们必须创建一个迭代器,该迭代器遍历游程编码序列。此处,迭代器通过调用RLEIterator(int [] A)进行初始化,其中A是序列的游程长度编码。因此我们可以说,对于所有偶数i,A [i]告诉我们在序列中重复非负整数值A [i + 1]的次数。这里的迭代器支持一个功能- nex