实战c++中的vector系列--emplace_back造成的引用失效
上篇将了对于struct或是class为何emplace_back要优越于push_back,可是另一些细节没有提及。今天就谈一谈emplace_back造成的引用失效。
直接撸代码了:
#include <vector>
#include <string>
#include <iostream>
using namespace std;
int main()
{
vector<int> ivec;
ivec.emplace_back(1);
ivec.emplace_back(ivec.back());
for (auto it = ivec.begin(); it != ivec.end(); ++it)
cout << *it << " ";
return 0;
}
//输出:
1 -572662307
尝试1:不直接给emplace_back传递ivec.back():
#include <vector>
#include <string>
#include <iostream>
using namespace std;
int main()
{
vector<int> ivec;
ivec.emplace_back(1);
auto &it = ivec.back();
ivec.emplace_back(it);
for (auto it = ivec.begin(); it != ivec.end(); ++it)
cout << *it << " ";
return 0;
}
输出:
1 -572662307
尝试2:不给emplace_back传递引用:
#include <vector>
#include <string>
#include <iostream>
using namespace std;
int main()
{
vector<int> ivec;
ivec.emplace_back(1);
auto it = ivec.back();
ivec.emplace_back(it);
for (auto it = ivec.begin(); it != ivec.end(); ++it)
cout << *it << " ";
return 0;
}
输出:
1 1
我们如愿以偿,这时候应该能够得到结论了,ivec.back()返回的是引用,可是这个引用失效了,所以才会输出不对;我们之前也提到过,又一次分配内存会造成迭代器的失效,这里是造成了引用的失效。
再回头看看emplace_back的描写叙述:
if a reallocation happens, all iterators, pointers and references related to this container are invalidated.
Otherwise, only the end iterator is invalidated, and all other iterators, pointers and references to elements are guaranteed to keep referring to the same elements they were referring to before the call.
进一步。
尝试3:避免emplace_back引起又一次分配内存:
#include <vector>
#include <string>
#include <iostream>
using namespace std;
int main()
{
vector<int> ivec;
ivec.reserve(4);
ivec.emplace_back(1);
ivec.emplace_back(ivec.back());
for (auto it = ivec.begin(); it != ivec.end(); ++it)
cout << *it << " ";
return 0;
}
输出:
1 1
可是这个时候问题来了,假设不使用emplace_back而改用push_back呢?
#include <vector>
#include <string>
#include <iostream>
using namespace std;
int main()
{
vector<int> ivec;
ivec.push_back(1);
ivec.push_back(ivec.back());
ivec.push_back(ivec.back());
ivec.push_back(ivec.back());
for (auto it = ivec.begin(); it != ivec.end(); ++it)
cout << *it << " ";
return 0;
}
//输出:
1 1 1 1
为什么使用push_back就不失效呢?
实战c++中的vector系列--emplace_back造成的引用失效的更多相关文章
- 实战c++中的vector系列--再谈vector的insert()方法(都是make_move_iterator惹的祸)
之前说过了关于vector的insert()方法,把vector B的元素插入到vector A中.vector A中的结果我们可想而知,可是vector B中的元素还会怎样? 看看之前写过的程序: ...
- 实战c++中的vector系列--知道emplace_back为何优于push_back吗?
上一篇博客说道vector中放入struct.我们先构造一个struct对象.再push_back. 那段代码中,之所以不能使用emplace_back,就是由于我们定义的struct没有显示的构造函 ...
- 实战c++中的vector系列--vector应用之STL的find、find_if、find_end、find_first_of、find_if_not(C++11)
使用vector容器,即避免不了进行查找,所以今天就罗列一些stl的find算法应用于vector中. find() Returns an iterator to the first element ...
- 实战c++中的vector系列--将迭代器转换为索引
stl的迭代器非常方便 用于各种算法. 可是一想到vector.我们总是把他当做数组,总喜欢使用下标索引,而不是迭代器. 这里有个问题就是怎样把迭代器转换为索引: #include <vecto ...
- 实战c++中的vector系列--构造、operator=和assign差别
vector或许是实际过程中使用最多的stl容器.看似简单,事实上有非常多技巧和陷阱. 着重看一看vector的构造,临时依照C++11: default (1) explicit vector (c ...
- 实战c++中的vector系列--creating vector of local structure、vector of structs initialization
之前一直没有使用过vector<struct>,如今就写一个简短的代码: #include <vector> #include <iostream> int mai ...
- 实战c++中的vector系列--正确释放vector的内存(clear(), swap(), shrink_to_fit())
关于vector已经写的差不多了,似乎要接近尾声了,从初始化到如何添加元素再到copy元素都有所涉及,是时候谈一谈内存的释放了. 是的,对于数据量很小的vector,完全没必要自己进行主动的释放,因为 ...
- 实战c++中的vector系列--copy set to vector(别混淆了reserve和resize)
stl算法中有个copy函数.我们能够轻松的写出这种代码: #include <iostream> #include <algorithm> #include <vect ...
- 实战c++中的vector系列--vector<unique_ptr<>>初始化(全部权转移)
C++11为我们提供了智能指针,给我们带来了非常多便利的地方. 那么假设把unique_ptr作为vector容器的元素呢? 形式如出一辙:vector<unique_ptr<int> ...
随机推荐
- 设计模式之一:strategy pattern
定义算法族,彼此之间可以替换.变化的方法抽出封装,不变的父类定义继承.多用组合少用继承. 代码示例先不贴了.
- laravel 只有/login路由403,如何解决
链接/login自动转跳到/login/导致找不到 /public/login/ 目录导致403; 将路由中\login改为\login1访问正常,但login依然403,而不是未找到路由 链接/lo ...
- h5 移动端 监听软键盘弹起、收起
前面一篇博客 h5 安卓 键盘弹起界面适配 修改webview高度提到了在adnroid中如何监听软键盘的弹起与收起,是利用的窗口的高度发生变化window.onresize事件来做突破点的,但是io ...
- Seating Arrangement
1997: Seating Arrangement Time Limit: 1 Sec Memory Limit: 128 Mb Submitted: 543 Solved: ...
- java_线程的通信
线程的通信共有三个方法: wait()运行时阻塞,释放锁 notify()唤醒阻塞线程 notifll()唤醒全部阻塞线程 public class ThreadTest01 { public sta ...
- 2.10.3 nav 元素
nav <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <tit ...
- zeng studio的项目窗口PHP Explorer
恢复zeng studio的项目窗口PHP Explorer方法: Windows>show view >PHP Explorer
- extjs动态添加列
可以根据日期,动态的插入一列 controller层: StdDayWordQuery:function(btn,event){ var form=Ext.getCmp('queryFormSDW') ...
- cc.Node—坐标系统
cc.Vec21: cc.Vec2 二维向量坐标, 表结构{x: 120, y: 120}; cc.v2(x, y) 创建一个二维向量 cc.p() 创建一个二外向量;2: cc.pSub: 向量相减 ...
- 两种js下载文件的方法(转)
function DownURL(strRemoteURL, strLocalURL){ try{ var xmlHTTP = new ActiveXObject("Microsoft.XM ...