对于哪个标准容器(如果有的话),end()返回的迭代器是持久化的
For which standard container, if any, is the iterator returned by end() persistent?
我需要一种方法来快速访问容器中的数据。
我记得那个数据位置的迭代器。在此之后,容器可能会被修改(添加和删除元素),但如果我使用的容器类型不会使我的迭代器无效(如std::map
或std::list
),我就没事了。
也我的数据可能不在容器(尚未),所以我设置了一个迭代器为container.end()
来反映这一点。
哪个标准容器保证end()
在添加和删除元素时不会改变?因此,我仍然可以将我的迭代器与container.end()
返回的值进行比较,而不会得到假阴性
23.2.4/9 of Associative Containers:
插入和放置构件不影响构件的有效性对容器的迭代器和引用,以及erase成员只使迭代器和对已删除元素的引用无效
现在,标准中有一些地方谈到不使"迭代器和对容器元素的引用"失效,因此不包括end()
。我不相信这是其中之一——我很确定end()
迭代器是一个"容器迭代器"。
23.3.5.4/1说std::list
的insert
"不影响迭代器和引用的有效性",而23.3.5.4/3说erase
"只使被擦除元素的迭代器和引用无效"。同样,end()
迭代器也是迭代器,因此不排除其有效性。
需要注意的一点是,对于任何容器,swap
都可以使end()迭代器无效(我认为这是因为有两种"自然"行为,结束迭代器要么指向相同容器的末端,要么指向被交换的容器的末端,但标准不想规定哪一种或排除其他可能性)。但是你没有交换,只是添加和删除元素。
根据我的经验,std::vector
和std::dequeue
中的迭代器在擦除或添加时调整大小时会中断(这也适用于std::string
的存储)。std::list
和std::map
不分配内存块:它们通常分配单个节点(并且大多数std::unordered_map
实现将bucket作为项目的链表(例如std::list
))。
如果你需要一个幸存的end()
迭代器,选择一个std::list
(我这样做是为了我的信号/插槽实现,为了他们的令牌)或者用std::vector
/std::dequeue
做你自己的个人记账。
编辑
:因此,std::list
是一种让迭代器始终有效的好方法,前提是列表本身永远不会死亡(它们不会死亡)。从另一个答案,如果你需要标准的清晰度:
23.3.5.4/1说for std::list insert"不影响迭代器和引用的有效性",而23.3.5.4/3说erase"只使被删除元素的迭代器和引用无效"。同样,end()迭代器也是迭代器,因此不排除它们的有效性。——另一个答案
使用vector
代替迭代器并存储索引值。他们会在任何重组中幸存下来。迭代器主要用于成对使用,用于指定一个范围;正如您所看到的那样,保留单个迭代器会变得很混乱。
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 什么时候在C++中返回常量引用是个好主意
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 如何使用 SFINAE 从 end() 方法返回 (const_) 迭代器
- 为什么空 unordered_map.find 不返回 end()?
- std::list.end() 不返回"past-the-end"迭代器
- 完全从c 中从std :: set.end()返回的内容
- 迭代器:如果 '*' 返回元素的引用,为什么删除 *(myList.end()) 会给出 SegFault
- 从end()函数返回的迭代器中获取BST的最后一个节点
- 集合数据结构中的 end() 迭代器应该返回什么
- 容器中的 begin() 和 end() 方法应始终具有相同的返回类型
- 我可以专门使用 std::begin 和 std::end 来获取 equal_range() 的返回值吗?
- 使用 std::vector 作为 std::map 的键在未找到和使用 reserve() 时不会返回 end()
- std::find返回vec.end(),而不管值是否在vector中
- 为我的向量包装器和迭代器返回'begin'和'end'函数返回什么?
- Qt容器(QVector,QList)::end()返回一个无法引用的迭代器
- 为什么stl_tree.h中的end()返回对迭代器对象的引用,而begin()返回object ?
- 对于哪个标准容器(如果有的话),end()返回的迭代器是持久化的
- 多个返回语句或"goto end;"
- 如果未找到映射条目,则返回特定的映射条目而不是 map::end