对于哪个标准容器(如果有的话),end()返回的迭代器是持久化的



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

我记得那个数据位置的迭代器。在此之后,容器可能会被修改(添加和删除元素),但如果我使用的容器类型不会使我的迭代器无效(如std::mapstd::list),我就没事了。

也我的数据可能不在容器(尚未),所以我设置了一个迭代器为container.end()来反映这一点。

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

23.2.4/9 of Associative Containers:

插入和放置构件不影响构件的有效性对容器的迭代器和引用,以及erase成员只使迭代器和对已删除元素的引用无效

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

23.3.5.4/1说std::listinsert"不影响迭代器和引用的有效性",而23.3.5.4/3说erase"只使被擦除元素的迭代器和引用无效"。同样,end()迭代器也是迭代器,因此不排除其有效性。

需要注意的一点是,对于任何容器,swap都可以使end()迭代器无效(我认为这是因为有两种"自然"行为,结束迭代器要么指向相同容器的末端,要么指向被交换的容器的末端,但标准不想规定哪一种或排除其他可能性)。但是你没有交换,只是添加和删除元素。

根据我的经验,std::vectorstd::dequeue中的迭代器在擦除或添加时调整大小时会中断(这也适用于std::string的存储)。std::liststd::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代替迭代器并存储索引值。他们会在任何重组中幸存下来。迭代器主要用于成对使用,用于指定一个范围;正如您所看到的那样,保留单个迭代器会变得很混乱。

相关内容

最新更新