deque迭代器失效的困惑?
在实现LRU算法的时候lru_list 開始用的是deque 可是由于害怕其在插入删除上的迭代器失效情况的诡异情况。遂用list取代之。
在数据量比較大的时候性能不是非常好。性能优化分析的时候决定用deque替换回来。于是对deque迭代器失效的情况好好研究了一下:
c++ primer如此写道:
1.在deque容器首部或者尾部插入元素不会使得不论什么迭代器失效。
2.在其首部或尾部删除元素则仅仅会使指向被删除元素的迭代器失效。
3.在deque容器的不论什么其它位置的插入和删除操作将使指向该容器元素的全部迭代器失效。
stackoverflow上对此的讨论:Confusion
on iterators invalidation in deque
|
完美的答案:
IMHO, deque is collection of blocks with first block growing in one direction and the last block in opposite direction.
Your opinion is your prerogative, but it's wrong. :)
deque is
such a container semantically, but in terms of implementation it's designed to be implemented by one or more blocks of memory. C++'s
iterator invalidation rules come from implementation, so this is why. Arguably this is a small abstraction leak but, well, whatever.
The SGI STL documentation is not the proper documentation to read, because the
SGI STL is not the C++ Standard Library. Unfortunately, Josuttis is one of those people who calls it "the STL", and this has led to your confusion.
Following is the excerpts from -- The C++ Standard Library: A Tutorial and Reference, By Nicolai M. Josuttis
Any insertion or deletion of elements other than at the beginning or end invalidates all pointers, references, and iterators that refer to elements
of the deque.
Put simply, this passage from Josuttis is misleading in implying that the insertion or deletion of elements thatare at
the beginning or end do not invalidate pointers, references or iterators … though it's worth noting that he never comes out and asserts this outright.
Here are the real, proper, official rules for std::deque:
C++03
Insertion: all iterators and references are invalidated, unless the inserted member is at an end (front or back) of the deque (in which case all
iterators are invalidated, but references to elements are unaffected) [23.2.1.3/1]Erasure: all iterators and references are invalidated, unless the erased members are at an end (front or back) of the deque (in which case only iterators
and references to the erased members are invalidated) [23.2.1.3/4]Resizing: as per insert/erase [23.2.1.2/1]
C++11
Insertion: all iterators and references are invalidated, unless the inserted member is at an end (front or back) of the deque (in which case all
iterators are invalidated, but references to elements are unaffected) [23.3.3.4/1]Erasure: erasing the last element invalidates only iterators and references to the erased elements and the past-the-end iterator; erasing the first
element invalidates only iterators and references to the erased elements; erasing any other elements invalidates all iterators and references (including the past-the-end iterator) [23.3.3.4/4]Resizing: as per insert/erase [23.3.3.4/1]
Further reading
deque迭代器失效的困惑?的更多相关文章
- C++中防止STL中迭代器失效——map/set等关联容器——vector/list/deque等序列容器—如何防止迭代器失效—即erase()的使用
序列性容器::(vector和list和deque) erase迭代器不仅使所有指向被删元素的迭代器失效,而且使被 删元素之后的所有迭代器失效,所以不能使用erase(iter++)的方 式, ...
- C++ STL 迭代器失效问题
之前看<C++ Primier>的时候,也解到在顺序型窗口里insert/erase会涉及到迭代器失效的问题,并没有深究.今天写程序的时候遇到了这个问题. 1 莫名其妙的Erase 最初我 ...
- STL的erase()陷阱-迭代器失效总结
下面材料整理自Internet&著作. STL中的容器按存储方式分为两类,一类是按以数组形式存储的容器(如:vector .deque):另一类是以不连续的节点形式存储的容器(如:list.s ...
- C++ Primer : 第九章 : 顺序容器的操作以及迭代器失效问题
顺序容器的添加.访问.删除操作以及forward_list的特殊操作,还有迭代器失效问题. 一.向容器添加元素 // array不支持这些操作 // forward_list有自己撰于的版本的inse ...
- C++ STL中迭代器失效的问题
my_container.erase(iter); 其中my_container是STL的某种容器,iter是指向这个容器中某个元素的迭代器.如果不是在for,while循环中,这种方式删除元素没有问 ...
- 容器大小的改变以及容器操作可能使迭代器失效、vector对象的容量变化
1 改变容器的大小 我们可以使用resize来增加或缩小容器,与往常一样,array不支持resize.如果当前大小大于所要求的大小,容器后面的元素会被删除:如果当前大小小于新大小,会将新元素添加到容 ...
- STL源代码分析--迭代摘要、迭代器失效汇总
Vector 1.内部数据结构:连续存储,比如数组. 2.随机訪问每一个元素,所须要的时间为常量. 3.在末尾添加或删除元素所需时间与元素数目无关,在中间或开头添加或删除元素所需时间随元素数目呈线性变 ...
- stl vector、红黑树、set、multiset、map、multimap、迭代器失效、哈希表(hash_table)、hashset、hashmap、unordered_map、list
stl:即标准模板库,该库包含了诸多在计算机科学领域里所常用的基本数据结构和基本算法 六大组件: 容器.迭代器.算法.仿函数.空间配置器.迭代适配器 迭代器:迭代器(iterator)是一种抽象的设计 ...
- C++迭代器失效的几种情况总结
一.序列式容器(数组式容器) 对于序列式容器(如vector,deque),序列式容器就是数组式容器,删除当前的iterator会使后面所有元素的iterator都失效.这是因为vetor,deque ...
随机推荐
- Java基础学习总结(33)——Java8 十大新特性详解
Java8 十大新特性详解 本教程将Java8的新特新逐一列出,并将使用简单的代码示例来指导你如何使用默认接口方法,lambda表达式,方法引用以及多重Annotation,之后你将会学到最新的API ...
- 2015 Multi-University Training Contest 5 hdu 5348 MZL's endless loop
MZL's endless loop Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Oth ...
- Linux下Makefile的automake生成全攻略
作为Linux下的程序开发人员,大家一定都遇到过Makefile,用make命令来编译自己写的程序确实是很方便.一般情况下,大家都是手工写一个简单Makefile,如果要想写出一个符合自由软件惯例的M ...
- dexposed框架Android在线热修复
移动client应用相对于Webapp的最大一个问题每次出现bug,不能像web一样在server就完毕修复,不须要发版本号.紧急或者有安全漏洞的问题, 假设是Webapp你可能最多花个1,2个小时紧 ...
- mvc架构的简单登录系统,jsp
文件结构 三个jsp文件负责前段界面的实现 login.jsp <%@ page language="java" import="java.util.*" ...
- 在Visual Studio Code中使用C#以及.net core
Working with C# Using .NET Core in Visual Studio Code Note: VS Code does not support debugging appli ...
- iOS (封装)一句话调用系统的alertView和alertController
前言: 本文仅作参考存留,请用新版封装:iOS 更加优雅便捷的UIAlertView/UIAlertController封装使用 UIAlertController是iOS8.0之后出来的新方法,其将 ...
- sql/plus无法显示数据库问题
登录PL/SQL Developer 这里省略Oracle数据库和PL/SQL Developer的安装步骤,注意在安装PL/SQL Developer软件时,不要安装在Program Files ( ...
- 基于localStorage的登录注册
以下代码,如果有地方有错,请直接指出,我会改进的(只改错误,不改逻辑,因为我自己是不会这样写代码的,这个只适合初学者): <!DOCTYPE html> <html> < ...
- <Three.js>(第三节)全景漫游
一.实验内容 通过上次实验,了解了Three.js创建场景的基本步骤.这一节,我们将通过Three.js实现全景漫游功能.如下图: 全景图是获取一个3D场景中的不同角度的图片,然后通过拼接.融合实现3 ...