vector的 emplace 和 insert 以及使用vector进行iterator遍历 且 erase的时候注意事项
- vector<int> first;//Size()==2
- first.push_back();
- first.push_back();
- //first.insert(2);
- vector<int>second;//Size()==3 + assign??
- second.push_back();
- second.push_back();
- second.push_back();
- vector<int>::iterator it = first.begin();
- //second.assign(it,first.end());
- second.insert(second.end(),first.begin(),first.end());
- printf("first.size=%d\n", first.size());
- printf("second.size=%d\n", second.size());
- for (it = second.begin(); it != second.end(); it++)
- printf("second[]=%d\n", *it);
second 要插入first的内容,太长了。好麻烦。怎么就没有直接 push_back(vector) 的 重构函数呢??
emplace 是C++11 里的 ,感觉跟这个 insert用法是一样的啊。
assign 是完全替换的意思。 直接用 operator = 难道不就OK了么?
reserve是修改vector目前数组 的大小。配套的是capacity()方法。获取数组的大小。
resize是修改vector 内容的。配套的是size()方法。获取数据的个数。 size() <= capacity();
--------------
真想把 www.cplusplus.com 这个网站给抓下来,然后自己做一个站点。
它没有评论;有些示例 非常不好。
补充 vector 进行iterator 且 erase删除元素的注意事项
==============================
【1】 首先,了解vector是数组,删除元素 会把后面的元素前移。
for( iterator it =XX.begin();it!=XX.end();it++){...}
【2】这里的it++ 只是 从前一个数组元素 移动到后一个数组元素,一般都是比较连续的地址,跟 vector<>里面的元素大小有关。
【3】而且for循环中 it!=XX.end() 这个条件 是一个坑,因为 它 不是实时的,当元素删除后,XX.end() 的值(地址) 应该会变动,但是for循环中 不会。所以 for循环 中间的条件 最好 在 for循环内 代码区域 进行判断,则是实时的【我的描述能力实在有限,只能这么说了】。
【4】可以使用 reverse_iterator 配合 erase 进行删除就安全一点
下面给一个例子:
- #include <stdio.h>
- #include <vector>
- using namespace std;
- void iteratorVector(vector <int>&vInts){
- int i = ;
- for (vector<int>::iterator it = vInts.begin(); it != vInts.end(); it++){
- printf("\t[%d] => %d\n", i++, *it);
- }
- printf("===== End Iterator Vector ====\n");
- }
- void test_erase(vector<int>&vInts, int nId)
- {
- for (vector<int>::iterator it = vInts.begin(); it != vInts.end(); it++){
- if (*it == nId){
- it = vInts.erase(it);
- return;
- }
- }
- }
- void test_reverse_iterator_vector(vector<int> & vInts)
- {
- //这里的 rbegin 应该 和 iterator 的end() 类似;
- //这里的 rend 应该 和 iterator 的 begin() 类似;
- for (vector<int>::reverse_iterator it = vInts.rbegin(); it != vInts.rend(); it++){
- test_erase(vInts, *it);
- iteratorVector(vInts);
- }
- return;
- //==== 等效代码 ====
- for (vector<int>::iterator it = vInts.end();;){
- if (it == vInts.begin())break;
- it--;
- test_erase(vInts, *it);
- iteratorVector(vInts);
- }
- }
- int main()
- {
- vector<int> playingUserID;
- playingUserID.push_back();
- playingUserID.push_back();
- playingUserID.push_back();
- playingUserID.push_back();
- playingUserID.push_back();
- iteratorVector(playingUserID);
- test_reverse_iterator_vector(playingUserID);
- }
- /*
- 运行结果:符合预期
- --------------
- test_vector_rbegin_with_erase.obj
- [0] => 1
- [1] => 2
- [2] => 3
- [3] => 4
- [4] => 5
- ===== End Iterator Vector ====
- [0] => 1
- [1] => 2
- [2] => 3
- [3] => 4
- ===== End Iterator Vector ====
- [0] => 1
- [1] => 2
- [2] => 3
- ===== End Iterator Vector ====
- [0] => 1
- [1] => 2
- ===== End Iterator Vector ====
- [0] => 1
- ===== End Iterator Vector ====
- ===== End Iterator Vector ====
- */
【5】如果要结合 iterator 与erase进行删除,那么要这么写代码:
- void test_iterator_vector(vector<int> & vInts)
- {
- for (vector<int>::iterator it = vInts.begin(); ; ){
- if (it == vInts.end())break;
- test_erase(vInts, *it);
- iteratorVector(vInts);
- }
- }
- /*
- [0] => 1
- [1] => 2
- [2] => 3
- [3] => 4
- [4] => 5
- ===== End Iterator Vector ====
- [0] => 2
- [1] => 3
- [2] => 4
- [3] => 5
- ===== End Iterator Vector ====
- [0] => 3
- [1] => 4
- [2] => 5
- ===== End Iterator Vector ====
- [0] => 4
- [1] => 5
- ===== End Iterator Vector ====
- [0] => 5
- ===== End Iterator Vector ====
- ===== End Iterator Vector ====
- */
这里没有了 it ++ ,因为 erase删除后,后面的元素 前移,那么 it 刚才所指向的地址 ,现在 就是后一个元素了,刚好用到,就不需要 it ++ -- 了。
顺便说下: it=vInts.erase(it); 这样 也是OK 的!!!!!
【6】 最后要说的就是 STL 中的vector 以及其他容器 都是 非线程安全的,使用 iterator 迭代器 ,和 插入元素 不进行 加锁控制,会导致严重的问题。
所以最好 自己 写一个 继承了 Mutex 功能的类的容器,使用stl 也就是这点风险了。
vector的 emplace 和 insert 以及使用vector进行iterator遍历 且 erase的时候注意事项的更多相关文章
- vector源码3(参考STL源码--侯捷):pop_back、erase、clear、insert
vector源码1(参考STL源码--侯捷) vector源码2(参考STL源码--侯捷):空间分配.push_back vector源码(参考STL源码--侯捷)-----空间分配导致迭代器失效 v ...
- STL—— 容器(vector)数据插入insert()方法 的返回值
vector 容器下的 insert() 方法拥有返回值,由于insert() 方法拥有4种重载函数,他的返回值不尽相同. 第一种,插入单个元素后的返回值: 1 #include <iostre ...
- emplace与insert的区别(C++11)
转自时习之 C++11中大部分的容器对于添加元素除了传统的 insert 或者 pusb_back/push_front 之外都提供一个新的函数叫做 emplace. 比如如果你想要向 std::ve ...
- 用vector容器代替数组 ——使用数组初始化vector对象
在C++中,我们不能用数组直接初始化另一数组,而只能创建新的数组,然后显式的把原数组的元素逐个复制给新的数组. 按照C语言中的做法: const size_t arry_size=6; int int ...
- 【转】vector中erase()的使用注意事项
vector::erase():从指定容器删除指定位置的元素或某段范围内的元素 vector::erase()方法有两种重载形式 如下: iterator erase( iterator _Whe ...
- C++中标准容器Vector,元素操作.insert()小结
insert() 函数有以下三种用法: iterator insert( iterator loc, const TYPE &val ); //在指定位置loc前插入值为val的元素,返回指 ...
- C++中使用vector.erase()需要注意的事项
本人菜鸟一枚.. 今天在用vector.erase()的时候,发现总是不能把应该erase掉的东西erase干净. 举个栗子: vector<int> num_vec; num_vec.p ...
- 18. Word Ladder && Word Ladder II
Word Ladder Given two words (start and end), and a dictionary, find the length of shortest transform ...
- 【JAVA、C++】LeetCode 018 4Sum
Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = tar ...
随机推荐
- 咏南IOCP中间件支持海量并发方案(集群)
咏南IOCP中间件支持海量并发方案(集群) 支持D7~XE10.1.1开发 支持负载均衡,自动故障转移 可以在不停机的状态下,根据负载情况灵活增加中间件机器 中间件使用IOCP通信,单中间件支持并发数 ...
- eclipse里面设置JVM参数的问题
在run----run configuration---Agruments里面设置JVM的参数: -Xms256m -Xmx1024m 肯定还有别的方式设置,今天就先写这一种方法.待续...
- 解决VMware下安装Ubuntu15不支持1920X1080分辨率的问题
解决步骤如下: flashmx@ubuntu:~$ cvt # 192.07M9) hsync: 67.16 kHz; pclk: 173.00 MHz Modeline -hsync +vsync ...
- 关于调整浏览器窗口JS
有时候需要对浏览器窗口的大小进行元素的操控,当调整窗口大小时用window.onresize=function(){} 页面初始化window.onload=function(){} 要注意的是onr ...
- BZOJ3174 Tjoi2013 拯救小矮人(贪心+DP)
传送门 Description 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口.对于每一个 ...
- C3P0连接池异常
解决方案: 将c3p0.jar包换成c3p0-0.9.0.2.jar,c3p0这个包应该有bug 引用如下: com.mchange.v2.log.MLog Determines which libr ...
- 揭秘Sql2014新特性-tempdb性能提升
一直以来,在高负载,复杂的生产环境中,tempdb的压力是成为整个实例瓶颈的重要因素之一.微软的工程师们也在各个版本中不断优化它的使用.到了Sql Server2014又有了新的特性使其性能得temp ...
- ASP.NET Web API 2 中的特性路由
ASP.NET MVC 5.1 开始已经支持基于特性的路由(http://attributerouting.net),ASP.NET WEB API 2 同时也支持了这一特性. 启用特性路 由只需要在 ...
- 博客恢复更新 工作环境转移到Linux
嗯, 回来了. 工作了, 以后学习和写博的时间只能靠挤了, 相信挤一挤总会有的.最近的一些计划: 重拾基础 玩好linux wid, 2014-04-27
- [WinAPI] 串口1-创建[包括: 打不开串口]
本来是用一个USB扩展把一个USB括成4个,然后把USB转串口连接上,虽然设备管理器可以找到用SSCOM也能找到,但是用API就是打不开,最后把USB转串插在电脑的一个USB上就可以啦! #inclu ...