上篇将了对于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造成的引用失效的更多相关文章

  1. 实战c++中的vector系列--再谈vector的insert()方法(都是make_move_iterator惹的祸)

    之前说过了关于vector的insert()方法,把vector B的元素插入到vector A中.vector A中的结果我们可想而知,可是vector B中的元素还会怎样? 看看之前写过的程序: ...

  2. 实战c++中的vector系列--知道emplace_back为何优于push_back吗?

    上一篇博客说道vector中放入struct.我们先构造一个struct对象.再push_back. 那段代码中,之所以不能使用emplace_back,就是由于我们定义的struct没有显示的构造函 ...

  3. 实战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 ...

  4. 实战c++中的vector系列--将迭代器转换为索引

    stl的迭代器非常方便 用于各种算法. 可是一想到vector.我们总是把他当做数组,总喜欢使用下标索引,而不是迭代器. 这里有个问题就是怎样把迭代器转换为索引: #include <vecto ...

  5. 实战c++中的vector系列--构造、operator=和assign差别

    vector或许是实际过程中使用最多的stl容器.看似简单,事实上有非常多技巧和陷阱. 着重看一看vector的构造,临时依照C++11: default (1) explicit vector (c ...

  6. 实战c++中的vector系列--creating vector of local structure、vector of structs initialization

    之前一直没有使用过vector<struct>,如今就写一个简短的代码: #include <vector> #include <iostream> int mai ...

  7. 实战c++中的vector系列--正确释放vector的内存(clear(), swap(), shrink_to_fit())

    关于vector已经写的差不多了,似乎要接近尾声了,从初始化到如何添加元素再到copy元素都有所涉及,是时候谈一谈内存的释放了. 是的,对于数据量很小的vector,完全没必要自己进行主动的释放,因为 ...

  8. 实战c++中的vector系列--copy set to vector(别混淆了reserve和resize)

    stl算法中有个copy函数.我们能够轻松的写出这种代码: #include <iostream> #include <algorithm> #include <vect ...

  9. 实战c++中的vector系列--vector&lt;unique_ptr&lt;&gt;&gt;初始化(全部权转移)

    C++11为我们提供了智能指针,给我们带来了非常多便利的地方. 那么假设把unique_ptr作为vector容器的元素呢? 形式如出一辙:vector<unique_ptr<int> ...

随机推荐

  1. uoj #15. 【NOIP2014】生活大爆炸版石头剪刀布

    石头剪刀布是常见的猜拳游戏:石头胜剪刀,剪刀胜布,布胜石头.如果两个人出拳一 样,则不分胜负.在<生活大爆炸>第二季第 8 集中出现了一种石头剪刀布的升级版游戏. 升级版游戏在传统的石头剪 ...

  2. Friday Q&A 2015-11-20:协变与逆变

    作者:Mike Ash,原文链接,原文日期:2015-11-20译者:Cee:校对:千叶知风:定稿:numbbbbb 在现代的编程语言中,子类型(Subtypes)和超类型(Supertypes)已经 ...

  3. CSS3 动画-- 鼠标移上去,div 会旋转、放大、移动

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. 【原】CentosDocker安装(一)

    CentosDocker安装 来源:https://www.runoob.com/docker/centos-docker-install.html 1.前提条件 目前,CentOS 仅发行版本中的内 ...

  5. bash基础——管道符、通配符

    1.多命令顺序执行 多命令顺序执行 格式 作用 ; 命令1 ; 命令2 多个命令之间没有任何逻辑联系 && 命令1&&命令2 逻辑与 当命令1正确执行,则命令2才会执行 ...

  6. hdfs深入:05、hdfs中的fsimage和edits的合并过程

    6.4.secondarynameNode如何辅助管理FSImage与Edits文件 ①:secnonaryNN通知NameNode切换editlog ②:secondaryNN从NameNode中获 ...

  7. 编译压缩代码 MFCompress-src-1.01 :对‘***’未定义的引用

    提示 MFCompressD.o:在函数‘main’中:MFCompressD.c:(.text.startup+0x34a): 警告: the use of `tempnam' is dangero ...

  8. Myeclipse下载

    地址:http://www.jb51.net/softs/593889.html#download

  9. java1.8学习-什么样的匿名内部类能被lambda语法代替?

    java1.8学习-什么样的匿名内部类能被lambda语法代替? java1.8好多新的特性真的很有意思,特别是Lambda.在学习的时候发现并不是所有的匿名内部类都可以用Lambda代替. lamb ...

  10. [Python3网络爬虫开发实战] 7.3-Splash负载均衡配置

    用Splash做页面抓取时,如果爬取的量非常大,任务非常多,用一个Splash服务来处理的话,未免压力太大了,此时可以考虑搭建一个负载均衡器来把压力分散到各个服务器上.这相当于多台机器多个服务共同参与 ...