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 ...
随机推荐
- oracle 的列转行函数 listagg()
当你的表X中有A,B两列,数据如下 A B a 1 a 2 a 3 b 1 b 2 b 3 想让数据以 a|1|2|3 , b|1|2|3 格式显示可使用listagg() 1.使用listagg() ...
- 封装HttpClient进行http请求与https请求
一.https忽略证书 /** * 用于进行Https请求的HttpClient * * @author joey * */ public class SSLClient { public stati ...
- TCL命令(事务控制)
确认提交DML操作:commit; 撤销DML操作:rollback; 提示:rollback撤销的是与上一个commit之间 所做的DML操作.注意:仅对 ...
- b.WHERE使用中多行子查询(适用于in,any,all条件)
b.多行子查询(适用于in,any,all条件) //查询与SCOTT和MARTIN在同一个部门的同事的编号和名称 select empno,ename from emp where ...
- ASP.NET-RedirectToAction只能使用get方法
两个同名Action共同使用return View() return RedirectToAction("test", new { ls = list.Fct_OrderList ...
- python实战之编码问题:中文!永远的痛
编码的思维图谱: 也就是说文件没有编码之说,事实上都是按二进制格式保存在硬盘中的.不过在写入读取时须使用相应的编码进行处理,以便操作系统配合相关软件/字体,绘制到屏幕中给人看.所以关键问题是得知道原先 ...
- shareSDK的初步使用(shareSDK中微信、qq等兼容问题,以及cocoapods支持架构冲突问题的解决)
第一次使用shareSDK来做第三方分享,可是.昨天一天都是在调试bug,一直错误不断! 先说下我的开发环境: xcode:5.1 真机调试:iPhone5s 我们都知道xcode5.1以后開始是支持 ...
- Linux 设备文件的创建和mdev
引子 本文是嵌入式企鹅圈开篇--<linux字符设备驱动剖析>的姐妹篇,在上述文章里面我们具体描写叙述了字符设备驱动框架涉及的驱动注冊.通过设备文件来訪问驱动等知识.并明白通过device ...
- hpc-ai比赛相关资料
http://follitude.com/blog/Use-RDMA-Emulation-in-Software-Using-SoftiWARP/ https://www.reflectionsoft ...
- win32编程 画图
void cDefense::DrawAll() { HDC hDc = GetDC(m_hWnd);//获取客户区窗口,如果该值为NULL,GetDC则获整个屏幕的窗口. HDC dcMem = C ...