上篇将了对于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. bat 时间 的运算与提取

    比如在系统中date这个环境变量的值为 -- 星期六 年------%date:~,% 表示从左向右指针向右偏0位,然后从指针偏移到的位置开始提取4位字符,结果是2011 月------%date:~ ...

  2. mysql中对order by的函数substring_index() , find_in_set()使用

    题目是这样的:sql = "select  *  from table  where  id  in(3,1,2,5)";  怎样使得查询的结果按照 3 ,1 , 2, 5来排序: ...

  3. comm - 逐行比较两个已排序的文件

    总览 (SYNOPSIS) ../src/comm [OPTION]... LEFT_FILE RIGHT_FILE 描述 (DESCRIPTION) 逐行比较 已排序的 文件 LEFT_FILE 和 ...

  4. sqlalchemy ORM进阶- 批量插入数据

    参考: https://www.jb51.net/article/49789.htm https://blog.csdn.net/littlely_ll/article/details/8270687 ...

  5. CAS机制总结

    一.简介 CAS机制:(Compare and set)比较和替换 简单来说–>使用一个期望值来和当前变量的值进行比较,如果当前的变量值与我们期望的值相等,就用一个新的值来更新当前变量的值CAS ...

  6. php简单实用的调试工具类

    <?php /* * 调试类 */ class Common_Debug { //打开错误报告 public static function showError($debug = true) { ...

  7. dedecms部分文章出现读取附加信息出错的解决办法

    问题: 估计是新版本开发的时候,没有考虑旧版,文章内容为空的新闻,新版不在允许文章内容为空的新闻,这样旧版的内容为空的新闻升级后将无法再编辑. 解决:你可以对如下文件进行如下修改:article_ed ...

  8. 认识单文件组件.vue 文件

    vuejs 自定义了一种.vue文件,可以把html, css, js 写到一个文件中,从而实现了对一个组件的封装, 一个.vue 文件就是一个单独的组件.由于.vue文件是自定义的,浏览器不认识,所 ...

  9. 【原】简单shell练习(一)

    1.交互式脚本 #!/bin/bash read -p "Enter your name:" name #read提示用户输入 echo "hello $name, we ...

  10. mysql cluster配置

    依赖包要求:cmake     gcc    gcc-c++     ncurses     Perl     ncurses-devel 在7.3以及更高的版本中, WITH_NDB_JAVA是默认 ...