实战c++中的vector系列--再谈vector的insert()方法(都是make_move_iterator惹的祸)
之前说过了关于vector的insert()方法,把vector B的元素插入到vector A中。vector A中的结果我们可想而知,可是vector B中的元素还会怎样?
看看之前写过的程序:
#include <iostream>
#include <vector>
int main ()
{
std::vector<int> myvector (3,100);
std::vector<int>::iterator it;
it = myvector.begin();
it = myvector.insert ( it , 200 );
myvector.insert (it,2,300);
// "it" no longer valid, get a new one:
it = myvector.begin();
std::vector<int> anothervector (2,400);
myvector.insert (it+2,anothervector.begin(),anothervector.end());
int myarray [] = { 501,502,503 };
myvector.insert (myvector.begin(), myarray, myarray+3);
std::cout << "myvector contains:";
for (it=myvector.begin(); it<myvector.end(); it++)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
如今关心一下别的:注意是insert后,被insert的vector为多少了:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> myvector(3, 100);
std::vector<int> anothervector(2, 400);
std::cout << "Before insert myvector is:";
for (auto it = myvector.begin(); it<myvector.end(); it++)
std::cout << ' ' << *it;
std::cout << std::endl;
std::cout << "Before insert anothervector is:";
for (auto it = anothervector.begin(); it<anothervector.end(); it++)
std::cout << ' ' << *it;
std::cout << std::endl;
myvector.insert(myvector.end(), anothervector.begin(), anothervector.end());
std::cout << "After insert myvector is:";
for (auto it = myvector.begin(); it<myvector.end(); it++)
std::cout << ' ' << *it;
std::cout << std::endl;
std::cout << "Now the anothervector is:";
for (auto it = anothervector.begin(); it<anothervector.end(); it++)
std::cout << ' ' << *it;
std::cout << std::endl;
int myarray[] = { 501,502,503 };
myvector.insert(myvector.begin(), myarray, myarray + 3);
std::cout << "After insert myarray[] to myvector, myvector is:";
for (auto it = myvector.begin(); it<myvector.end(); it++)
std::cout << ' ' << *it;
std::cout << std::endl;
std::cout << "After insert myarray[] to myvector, myarray[] is:";
for (int i = 0; i < 3; i++)
{
std::cout << ' ' << myarray[i];
}
return 0;
}
//输出:
//Before insert myvector is : 100 100 100
//Before insert anothervector is : 400 400
//After insert myvector is : 100 100 100 400 400
//Now the anothervector is : 400 400
//After insert myarray[] to myvector, myvector is : 501 502 503 100 100 100 400 400
//After insert myarray[] to myvector, myarray[] is : 501 502 503
假设你看到此时,你肯定会在心里骂娘,谁还关心vector B,而且vectorB并没有变化。
如今是时候来点猛药了。vector中放智能指针。
之前博客也讲诉过对于vector的元素为智能指针的时候:
#include<iostream>
#include<vector>
#include <memory>
using namespace std;
void display_vector(vector<unique_ptr<int>> &vec);
int main()
{
vector<unique_ptr<int>> vec;
unique_ptr<int> s1(new int(1));
unique_ptr<int> s2(new int(2));
unique_ptr<int> s3(new int(3));
unique_ptr<int> s4(new int(4));
vec.push_back(std::move(s1));
vec.push_back(std::move(s2));
vec.push_back(std::move(s3));
vec.push_back(std::move(s4));
unique_ptr<int> s5(new int(5));
vector<unique_ptr<int>> des_vec;
des_vec.push_back(std::move(s5));
des_vec.insert(des_vec.end(), std::make_move_iterator(vec.begin()), std::make_move_iterator(vec.end()));
display_vector(des_vec);
cout << "now, des_vec size: " << des_vec.size() << endl;
cout << "now, vec size: " << vec.size() << endl;
//display_vector(vec);
cout << "now, vec size: " << vec.size() << endl;
for (int i=0; i<vec.size(); i++)
{
cout << *vec[i] << " ";
}
return 0;
}
void display_vector(vector<unique_ptr<int>> &vec)
{
for (auto it = vec.begin(); it != vec.end(); it++)
{
cout << **it << endl;
}
}
上面代码会崩溃。原因就是vec被insert后 。vec变得无效了,我们不能对他做什么。。。。。
可是须要明白的是这不是insert造成的,假设copy也会造成这一的结局,事实上罪魁祸首就是make_move_iterator
再看程序:
#include <iostream>
#include <list>
#include <vector>
#include <string>
#include <iterator>
int main()
{
std::list<std::string> s{ "one", "two", "three" };
std::vector<std::string> v1(s.begin(), s.end()); // copy
std::vector<std::string> v2(std::make_move_iterator(s.begin()),
std::make_move_iterator(s.end())); // move
std::cout << "v1 now holds: ";
for (auto str : v1)
std::cout << "\"" << str << "\" ";
std::cout << "\nv2 now holds: ";
for (auto str : v2)
std::cout << "\"" << str << "\" ";
std::cout << "\noriginal list now holds: ";
for (auto str : s)
std::cout << "\"" << str << "\" ";
std::cout << '\n';
}
//输出:
//v1 now holds : "one" "two" "three"
//v2 now holds : "one" "two" "three"
//original list now holds : ""
最后再上一个官方程序:
#include <iostream> // std::cout
#include <iterator> // std::make_move_iterator
#include <vector> // std::vector
#include <string> // std::string
#include <algorithm> // std::copy
int main() {
std::vector<std::string> foo(3);
std::vector<std::string> bar{ "one","two","three" };
std::copy(make_move_iterator(bar.begin()),
make_move_iterator(bar.end()),
foo.begin());
// bar now contains unspecified values; clear it:
bar.clear();
std::cout << "foo:";
for (std::string& x : foo) std::cout << ' ' << x;
std::cout << '\n';
return 0;
}
* 须要注意:*
* bar.clear();*
因此此时: bar now contains unspecified values; clear it:
实战c++中的vector系列--再谈vector的insert()方法(都是make_move_iterator惹的祸)的更多相关文章
- 实战c++中的string系列--std:vector 和std:string相互转换(vector to stringstream)
string.vector 互转 string 转 vector vector vcBuf;string stBuf("Hello DaMao!!!");----- ...
- 实战c++中的vector系列--正确释放vector的内存(clear(), swap(), shrink_to_fit())
关于vector已经写的差不多了,似乎要接近尾声了,从初始化到如何添加元素再到copy元素都有所涉及,是时候谈一谈内存的释放了. 是的,对于数据量很小的vector,完全没必要自己进行主动的释放,因为 ...
- 微软BI 之SSIS 系列 - 再谈Lookup 缓存
开篇介绍 关于 Lookup 的缓存其实在之前的一篇文章中已经提到了 微软BI 之SSIS 系列 - Lookup 组件的使用与它的几种缓存模式 - Full Cache, Partial Cache ...
- 实战c++中的string系列--十六进制的字符串转为十六进制的整型(一般是颜色代码使用)
非常久没有写关于string的博客了.由于写的差点儿相同了.可是近期又与string打交道,于是荷尔蒙上脑,小蝌蚪躁动. 在程序中,假设用到了颜色代码,一般都是十六进制的,即hex. 可是server ...
- .Net中的AOP系列之《间接调用——拦截方法》
返回<.Net中的AOP>系列学习总目录 本篇目录 方法拦截 PostSharp方法拦截 Castle DynamicProxy方法拦截 现实案例--数据事务 现实案例--线程 .Net线 ...
- 别再眼高手低了! 这些Linq方法都清楚地掌握了吗?
不要再眼高手低了,这些Enumerable之常见Linq扩展方法都清楚掌握了吗?其实这是对我自己来说的! 例如:一个人这个技术掌握了一点那个技术也懂一点,其他的好像也了解一些,感觉自己啥都会一点,又觉 ...
- 实战c++中的string系列--string与char*、const char *的转换(data() or c_str())
在project中,我们也有非常多时候用到string与char*之间的转换,这里有个一我们之前提到的函数 c_str(),看看这个原型: const char *c_str(); c_str()函数 ...
- 实战c++中的string系列--不要使用memset初始化string(一定别这么干)
參考链接: http://www.cppblog.com/qinqing1984/archive/2009/08/07/92479.html 百度百科第一次这么给力: void *memset(voi ...
- 实战c++中的string系列--std::string与MFC中CString的转换
搞过MFC的人都知道cstring,给我们提供了非常多便利的方法. CString 是一种非常实用的数据类型. 它们非常大程度上简化了MFC中的很多操作,使得MFC在做字符串操作的时候方便了非常多.无 ...
随机推荐
- xml与json格式互转
最近要整一些报文测试的事情,可当前项目的请求报文格式却不统一,有XML也有JSON,为了一致性,决定统一用JSON格式处理. xmltodict : Makes working with XML fe ...
- Nagios监控nginx服务具体过程
1在nginx 服务器上安装nrpe客户端: Nginx的服务须要监控起来.不然万一down了而不及时修复,会影响web应用.例如以下web应用上面启动的nginx后台进程[root@lb-net-2 ...
- Android自己定义RatingBar
注意rating_background图片做出来的图片最好和图片四周有一定的空隙.不然会造成图片底部被拉伸的情况. <RatingBar android:layout_width="w ...
- 使用记事本开发第一个java程序
记事本是开发java程序最基础的一个工具 第一步:编写 新建一个文件名为Hello的文本文档,并将文件扩展名改为.java. 在文本框内输入我们的程序代码 ——————————————我是分割线——— ...
- Java-MyBatis:MyBatis3 | 日志
ylbtech-Java-MyBatis:MyBatis3 | 日志 1.返回顶部 1. 日志 Mybatis 的内置日志工厂提供日志功能,内置日志工厂将日志交给以下其中一种工具作代理: SLF4J ...
- [jzoj 6092] [GDOI2019模拟2019.3.30] 附耳而至 解题报告 (平面图转对偶图+最小割)
题目链接: https://jzoj.net/senior/#main/show/6092 题目: 知识点--平面图转对偶图 在求最小割的时候,我们可以把平面图转为对偶图,用最短路来求最小割,这样会比 ...
- 关于div中图片水平垂直居中的问题
最近在做一个项目,里面涉及到不固定尺寸要在div里面水平垂直居中显示 我没有用table布局,而是用了div+css,找了很久,终于在网上找到解决方案,特此记录备用 关键核心代码如下: <div ...
- android 给imageView,文字等加上阴影[记录]
1.链接 https://github.com/Devlight/ShadowLayout 2.效果 3.code compile 'com.github.devlight.shadowlayout: ...
- Golden Gate 检查点
检查点是记录读写位置信息,在恢复时候要用到,保证事务的完整性. 两种存储方式: 存放在dirchk下 存放在指定的checkpoint table Replicat: nodbcheckpoint: ...
- 伍、ajax
一.ajax的概念 通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新.这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新. 传统的网页(不使用 AJAX)如果需要更新 ...