1

我需要一种快速访问容器中数据的方法。

所以我记得那个数据位置的迭代器。之后可能会修改容器(添加和删除元素),但如果我使用不会使我的迭代器无效的容器类型(如std::mapor std::list)我很好。

另外我的数据可能不在容器中(还),所以我设置了一个迭代器container.end()来反映这一点。

哪个标准容器保证end()在添加和删除元素时不会改变?所以我仍然可以将我的迭代器与返回的值进行比较,container.end()而不会得到假阴性。

4

3 回答 3

6

23.2.4/9 说关联容器:

insert 和 emplace 成员不应影响迭代器和对容器的引用的有效性,而擦除成员应仅使迭代器和对被擦除元素的引用无效

现在,有些地方标准谈到不使“迭代器和对容器元素的引用”无效,因此不包括end(). 我不相信这是其中之一——我很确定end()迭代器是“容器的迭代器”。

23.3.5.4/1 表示std::listinsert不影响迭代器和引用的有效性”,而 23.3.5.4/3 表示erase“仅使迭代器和对已擦除元素的引用无效”。同样,end()迭代器是迭代器,因此不排除它们的有效性。

需要注意的一件事是,对于任何容器,swap都可以使 end() 迭代器无效(我认为这是因为有两种“自然”行为,即 end 迭代器指向同一个容器的末尾,或者指向末尾它被交换的一个,但标准不想规定或排除其他可能性)。但你不是在交换,只是添加和删除元素。

于 2013-03-14T16:30:47.127 回答
3

根据我的经验,迭代器从擦除或添加调整大小时会中断(这也适用于std::vector' s 的存储)。并且不分配内存块:它们通常分配单个节点(并且大多数实现将桶作为项目的链接列表(例如,))。std::dequeuestd::stringstd::liststd::mapstd::unordered_mapstd::list

如果您需要一个幸存的end()迭代器,请选择一个std::list(我这样做是为了我的 Signal/Slots 实现,为了他们的令牌)或使用std::vector/进行您自己的个人簿记std::dequeue

编辑:因此,std::list如果您的列表本身永远不会消失(它们不会),那么这是让您的迭代器始终有效的好方法。从另一个答案中,如果您需要标准的清晰度:

23.3.5.4/1 说 std::list 插入“不影响迭代器和引用的有效性”,而 23.3.5.4/3 说擦除“仅使迭代器和对被擦除元素的引用无效”。同样, end() 迭代器是迭代器,因此不排除它们的有效性。-另一个答案

于 2013-03-14T16:19:38.880 回答
0

代替迭代器,使用 avector并存储索引值。他们将在任何重组中幸存下来。迭代器主要用于指定范围的成对使用;如您所见,挂在单个迭代器上会变得混乱。

于 2013-03-14T16:19:48.583 回答