c++之使用emplace_back()取代push_back()

https://www.cnblogs.com/ChrisCoder/p/9919646.html

C++ STL迭代器原理和实现_05jin的博客-CSDN博客_stl迭代器实现

C++STL迭代器实现原理之三:迭代器的实现与使用_编程砖家的博客-CSDN博客_stl迭代器实现

  • push_back()函数向容器中加入一个临时对象(右值元素)时, 首先会调用构造函数生成这个对象,然后条用拷贝构造函数将这个对象放入容器中, 最后释放临时对象。但是emplace_back()函数向容器中中加入临时对象, 临时对象原地构造,没有赋值或移动的操作。
#include <vector>
#include <string>
#include <iostream>  struct President
{  std::string name;  std::string country;  int year;  President(std::string p_name, std::string p_country, int p_year)  : name(std::move(p_name)), country(std::move(p_country)), year(p_year)  {  std::cout << "I am being constructed.\n";  }President(const President& other): name(std::move(other.name)), country(std::move(other.country)), year(other.year){std::cout << "I am being copy constructed.\n";}President(President&& other)  : name(std::move(other.name)), country(std::move(other.country)), year(other.year)  {  std::cout << "I am being moved.\n";  }  President& operator=(const President& other);
};  int main()
{  std::vector<President> elections;  std::cout << "emplace_back:\n";  elections.emplace_back("Nelson Mandela", "South Africa", 1994); //没有类的创建  std::vector<President> reElections;  std::cout << "\npush_back:\n";  reElections.push_back(President("Franklin Delano Roosevelt", "the USA", 1936));  std::cout << "\nContents:\n";  for (President const& president: elections) {  std::cout << president.name << " was elected president of "  << president.country << " in " << president.year << ".\n";  }  for (President const& president: reElections) {  std::cout << president.name << " was re-elected president of "  << president.country << " in " << president.year << ".\n";
}
  • 据统计,emplace_back()函数要比push_back()函数要快一倍。

(700条消息) C++ std::pair的用法_std pair_吉大秦少游的博客-CSDN博客

C++ vector的reserve和resize详解

C++ vector的reserve和resize详解 - 篮球之神Michael - 博客园

vector 的reserve增加了vector的capacity,但是它的size没有改变!而resize改变了vector的capacity同时也增加了它的size!
原因如下:

reserve是容器预留空间,但在空间内不真正创建元素对象,所以在没有添加新的对象之前,不能引用容器内的元素。加入新的元素时,要调用push_back()/insert()函数。

resize是改变容器的大小,且在创建对象,因此,调用这个函数之后,就可以引用容器内的对象了,因此当加入新的元素时,用operator[]操作符,或者用迭代器来引用元素对象。此时再调用push_back()函数,是加在这个新的空间后面的。

list , vector  find

C++11 find和find_if的用法_zzhongcy的博客-CSDN博客_find_if

STL的find,find_if函数提供了一种对数组、STL容器进行查找的方法。使用该函数,需 #include <algorithm>
我们查找一个list中的数据,通常用find(),例如:

vector<string>::iterator iter;iter = find(channelInfo->begin(), channelInfo->end(), strategyId);auto find = 0;if (iter != channelInfo->end()){//vec中存在"SZ000001"find = 1;}

我们在CPerson类外部定义这样一个结构体:
typedef struct finder_t
{
    finder_t(int n) : age(n) { } 
    bool operator()(CPerson *p) 
    { 
        return (age == p->age); 
    } 
    int age;
}finder_t;

然后就可以利用find_if函数来查找了:
list<CPerson*> lst;
// 向lst中添加元素,此处省略

list<CPerson*>::iterator it = find_if(lst.begin(), lst.end(), finder_t(50)); // 查找年龄为50的人
if (it != lst.end()) // 找到了
{
    cout << "Found person with age : " << (*it)->age;
}
else // 没找到
{
    // do something
}

STL容器是线程不安全的----以及加锁实现多线程访问安全

STL容器是线程不安全的----以及加锁实现多线程访问安全_guochampion的博客-CSDN博客_stl容器是线程不安全的

一般说来,stl对于多线程的支持仅限于下列两点:(貌似Effective STL中有描述)

1.多个读取者是安全的。即多个线程可以同时读取一个容器中的内容。 即此时多个线程调用 容器的不涉及到写的接口都可以 eg find, begin, end 等.

2.对不同容器的多个写入者是安全的。即多个线程对不同容器的同时写入合法。 但是对于同一容器当有线程写,有线程读时,如何保证正确? 需要程序员自己来控制,比如:线程A读容器某一项时,线程B正在移除该项。这会导致一下无法预知的错误。 通常的解决方式是用开销较小的临界区(CRITICAL_SECTION)来做同步。以下列方式同步基本上可以做到线程安全的容器(就是在有写操作的情况下仍能保证安全)。

  1.每次调用容器的成员函数的期间需要锁定。

  2.每个容器容器返回迭代器的生存期需要锁定。

  3.每个容器在调用算法的执行期需要锁定。

  和小罗的关于task_server的多线程安全的交流: 是这样的, 当你调用map的任何接口时, 比如 end(), begin(), find()等时, 可能会返回一个iterator, 如果有别的线程正在修改这个map, 你的iterator就变得无效了, 再用这个iterator行为就可能出问题. 或者在find()函数内部, 会访问到map内部的红黑树的数据结构, 而这个红黑树是有可能被别的线程调整的(比如别的现在往map中插入一个不存在的记录). 所以, 是危险的.

我们通常通过为容器加锁来保证容器的线程安全性。

为容器加锁:

  • 多个读取者是安全的。多线程可能同时读取一个容器的内容,这将正确地执行。当然,在读取时不能有任何写入者操作这个容器。

  • 对不同容器的多个写入者是安全的。多线程可以同时写不同的容器。

多线程操作C++ STL vector出现概率coredump问题及尽量避免锁的双缓冲队列

多线程操作C++ STL vector出现概率coredump问题及尽量避免锁的双缓冲队列 - 大老虎打老虎 - 博客园

最后,回到我遇到的那个问题,定时更新配置,可以考虑加锁。如果不用锁, 该怎么实现呢? 可以考虑用两个vector, 轮换使用,更新的vector不去读, 当前的读的vector不更新,然后轮换当前vector.  我见过很多地方都是这么用的。

类似的问题还有很多很多, 坑, 就在那里, 不多不少。 书本Effective STL第12 条如是说:切勿对STL 容器的线程安全性有不切实际的依赖!

双缓冲队列文章,注意双缓冲队列不是完全不加锁 而是尽可能的减少加减锁

C++11 实现生产者消费者双缓冲

C++11 实现生产者消费者双缓冲 - karllen - 博客园

实现一个双缓冲队列 - 重庆肥猫 - 博客园

C++ STL中的 Set的用法

C++ STL中的 Set的用法 - 生活待我如初恋 - 博客园

set   是STL中的集合。

  集合我们都很熟悉,具有排异性,在这里set中也遵循这条规矩。 而且在set中,存在系统自动排序的操作。

C++/C++11中std::set用法汇总_Frank.Ginger的博客-CSDN博客_c++11 set

标准库提供8个关联容器:

(1)、按关键字有序保存元素:map(关联数组:保存关键字----值对);set(关键字即值,即只保存关键字的容器);multimap(关键字可重复出现的map);multiset(关键字可重复出现的set);

(2)、无序集合:unordered_map(用哈希函数组织的map);unordered_set(用哈希函数组织的set);unordered_multimap(哈希组织的map,关键字可以重复出现);unordered_multiset(哈希组织的sest,关键字可以重复出现)。

map是关键字----值对的集合,与之相对,set就是关键字的简单集合。当只是想知道一个值是否存在时,set是最有用的。

在set中每个元素的值都唯一,而且系统能根据元素的值自动进行排序。Set中元素的值不能直接被改变。set内部采用的是一种非常高效的平衡检索二叉树:红黑树,也称为RB树(Red-Black Tree)。RB树的统计性能要好于一般平衡二叉树。

下面是从cplusplus和cpp

list函数splice

list::splice()函数详解 - 小 楼 一 夜 听 春 雨 - 博客园

list::splice实现list拼接的功能。将源list的内容部分或全部元素删除,拼插入到目的list。

函数有以下三种声明:

void splice ( iterator position, list<T,Allocator>& x );  //

void splice ( iterator position, list<T,Allocator>& x, iterator i );

void splice ( iterator position, list<T,Allocator>& x, iterator first, iterator last );

函数说明:在list间移动元素:

将x的元素移动到目的list的指定位置,高效的将他们插入到目的list并从x中删除。

目的list的大小会增加,增加的大小为插入元素的大小。x的大小相应的会减少同样的大小。

前两个函数不会涉及到元素的创建或销毁。第三个函数会。

指向被删除元素的迭代器会失效。

// splicing lists
#include <iostream>
#include <list>int main ()
{std::list<int> mylist1, mylist2;std::list<int>::iterator it;// set some initial values:for (int i=1; i<=4; ++i)mylist1.push_back(i);      // mylist1: 1 2 3 4for (int i=1; i<=3; ++i)mylist2.push_back(i*10);   // mylist2: 10 20 30it = mylist1.begin();++it;                         // points to 2mylist1.splice (it, mylist2); // mylist1: 1 10 20 30 2 3 4// mylist2 (empty)// "it" still points to 2 (the 5th element)mylist2.splice (mylist2.begin(),mylist1, it);// mylist1: 1 10 20 30 3 4// mylist2: 2// "it" is now invalid.it = mylist1.begin();std::advance(it,3);           // "it" points now to 30mylist1.splice ( mylist1.begin(), mylist1, it, mylist1.end());// mylist1: 30 3 4 1 10 20std::cout << "mylist1 contains:";for (it=mylist1.begin(); it!=mylist1.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';std::cout << "mylist2 contains:";for (it=mylist2.begin(); it!=mylist2.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';return 0;
}

c++ stl find和find_if, 迭代器相关推荐

  1. C++中STL和容器、迭代器、算法之间的关系

    自学习C++以来,一直对STL.容器.迭代器.算法甚是困惑. 参考一些资料,加上自己的理解,整理如下 如果说程序等于数据结构+算法,STL就是一个小程序库,之所以说小,是因为容器模板中常用的函数有限, ...

  2. STL源码剖析 迭代器iterator的概念 和 traits编程技法

    iterator模式定义如下:提供一种方法,使之能够依序巡访某个 聚合物(容器)所含的各个元素,而又无需暴露该聚合物的内部表述方式. STL的中心思想在于:将数据容器(containers)和算法(a ...

  3. 【C++】STL中 list 反向迭代器的模拟实现

    在上篇文章实现了 list 后,我们实现了其对应的迭代器,但是对于 list,还有一个反向迭代器我们呢没有实现,但是反向迭代器不仅仅可以在 list 中使用,在 vector 中我们进行适配,同样也可 ...

  4. C++【STL】【反向迭代器】

    目录 一.反向迭代器的简介 1.什么是反向迭代器 2.方向迭代器的实现 二.反向迭代器的相关问题 1.为什么在operator*中需要--迭代器 2.适配list的反向迭代器 3.适配vector的反 ...

  5. SGL STL源码剖析——迭代器

    SGL STL源码剖析--迭代器 迭代器 迭代器的型别 Traits的作用 迭代器相应的五种型别 __type_traits 迭代器 在我们使用STL容器的时候,迭代器是非常常见的,STL将容器和算法 ...

  6. STL的erase()陷阱-迭代器失效总结

    下面材料整理自Internet&著作. STL中的容器按存储方式分为两类,一类是按以数组形式存储的容器(如:vector .deque):另一类是以不连续的节点形式存储的容器(如:list.s ...

  7. STL源码剖析---迭代器失效小结

    迭代器(iterator)是一个可以对其执行类似指针的操作(如:解除引用(operator*())和递增(operator++()))的对象,我们可以将它理解成为一个指针.但它又不是我们所谓普通的指针 ...

  8. STL中的find_if函数

    这是find()的一个更强大的版本.这个例子演示了find_if(),它接收一个函数对象的参数作为参数, 并使用它来做更复杂的评价对象是否和给出的查找条件相付. 假设我们的list中有一些按年代排列的 ...

  9. STL 之find,find_if,find_end,find_first_of

    作用:用来在一个指定的区间中查找元素. 1,find, find_if 原型: #include <algorithm> template <class inputItr,class ...

最新文章

  1. oracle library cache lock,【案例】Oracle等待事件library cache lock产生原因和解决办法...
  2. 金融学名词M0, M1, M2, M3, M4, M5, M6
  3. WCF与 Web Service的区别
  4. 【安全】从mimikatz学习Windows安全之访问控制模型
  5. 思科设备故障检测检查表
  6. 如何走近深度学习人脸识别?你需要这篇超长综述 | 附开源代码
  7. 20161114记录一件工作的事
  8. 论文学习9-Bidirectional LSTM-CRF Models for Sequence Tagging(LSTM,BILSTM,LSTM-CRF,BILSTM-CRF
  9. mysql计算订单总金额_mysql统计当天消费总额
  10. kappa和lambda对比 | 程序员硬核评测
  11. 无向图的深度优先遍历非递归_图算法总结
  12. 硬盘分区表和文件分配表格式
  13. 给 UITextField 添加左侧指示图片(类似微信登录框)
  14. 文案“跑路”了,这是我们的新广告语
  15. android图片底部居中对齐,Android 解决图文混排,图片和文字居中对齐问题(ImageSpan)...
  16. SetTimer函数总结
  17. 韦根w34是多少位_韦根协议格式
  18. 桥架算量用什么软件_鹏业安装算量软件识别桥架
  19. php怎么更换图片背景的软件,照片换背景颜色 照片换背景用什么软件|教你怎么换照片背景颜色...
  20. oracle同义词6,Oracle同义词

热门文章

  1. 关于springMvc如何返回字符串而不是被当做路径跳转
  2. 小白免费编程学习网站
  3. android TextView中间删除线显示
  4. 国产操作系统使用经历:红旗,深度,优麒麟
  5. dell服务器查看内存详细信息,DELL R710服务器内存故障排错
  6. 微盛研究| 加速扩张中的喜茶、奈雪们,为其它品牌提供了怎样的私域启示?
  7. 你是缓慢悠闲的“小辣鸡”,还是超尘逐电的“闪电侠”?
  8. 【Source教程】文章目录
  9. short、int、Integer、long取值范围
  10. Socket实现聊天室(二)