
STL实用技巧笔记
记录工作中用到的stl库工具用法
持续学习,不断沉淀
C++开发工程师
展开
-
条件变量(condition_variable)
一、定义:1.1、解释:条件变量是利用线程间共享的变量进行同步的一种机制,是在多线程程序中用来实现"等待–>唤醒"逻辑常用的方法,用于维护一个条件(与是条件变量不同的概念),线程可以使用条件变量来等待某个条件为真,注意理解并不是等待条件变量为真。当条件不满足时,线程将自己加入等待队列,同时释放持有的互斥锁; 当一个线程唤醒一个或多个等待线程时,此时条件不一定为真(虚假唤醒)。1.2、个人理解:两个线程利用条件变量及互斥锁实现同步。条件变量和互斥锁对两个线程来说是全局的。一个线程利用条件变原创 2022-04-19 00:53:00 · 12369 阅读 · 0 评论 -
std::ref用法
1、作用:std::ref 用于取某个变量的引用,引入其是为了解决函数式编程(如std::bind)的一些传参问题。2、用法:#include <functional>#include <iostream>void f(int& n1, int& n2, const int& n3){ std::cout << "In function: " << n1 << ' ' << n2 <&转载 2022-04-15 20:45:00 · 6737 阅读 · 0 评论 -
C++17 可选对象(std::optional)及operator bool ()、bool operator ==()操作符重载
1、用法:类模板 std::optional管理一个可选的值,既可以存在也可以不存在的值。模板原型: template< class T > class optional; 构造方式:std::optional<int> val1; // 构造可选值为空 std::optional<int> val2 = 1; // 构造值为1 2、使用场景:2.1、作为一个可能失败的函数的返回值:#include <optiona原创 2021-08-15 17:49:41 · 912 阅读 · 0 评论 -
C++11并发规则:临界区越短越好
将锁的作用域范围做到最小:std::mutex mutex_; 修改前:void func1() { std::lock_guard<std::mutex> lck(mutex_); num = 1; std::cout << "changed num" << std::endl;} 修改后:void func1() { // 缩短锁的生命周期/作用域 { std::lock_guard原创 2021-05-26 21:22:26 · 350 阅读 · 0 评论 -
std::vector与std::map的多线程读写问题
STL 语义上不提供任何强度的线程安全保证。1、vector与map都不是线程安全的:同时读OK同时写NO== 同时读写==NO2、vector读写情况:vector一般情况下同时读写读没问题,但当vector预留内存空间不足,需要扩容导致的变量搬移时,读存在问题,同时写也存在问题,因此需要加锁,防止并发执行。3、map读写情况:map底层结构时红黑树,每插入一个节点,map对下中数据分布就会变,因此,不可以同时写、也不能同时读写。参考资料:1、C++ ST原创 2021-05-25 19:20:07 · 6845 阅读 · 0 评论 -
C++完美转发实现原理:万能引用、引用折叠
1、概念:1.1、万能引用(Universal Reference):使用 T&&类型的形参既能绑定右值,又能绑定左值,只有发生类型推导的时候,T&&才表示万能引用 ;否则,表示右值引用。即万能引用只存在模板中,模板中的&&不代表右值引用,而是万能引用,其既能接收左值又能接收右值。1.2、左/右值引用变量的值类型都是左值:引用类型的唯一作用就是限制了接收的类型,后续使用中都退化成了左值;引用的值类型和变量类型不一样, 左/右值引用变量的值类型都是左值原创 2021-05-23 20:39:24 · 2467 阅读 · 1 评论 -
map用[]访问不存在的元素
1、代码示例:unordered_map<string, int> mymap1; auto val = mymap1["str"]; // val为0 // 常用于词频统计,存在则加一,不存在则创建后赋值为1 unordered_map<string, int> mymap2; mymap2["str"]++; // mymap2["str"] = 1 Map中使用方括号访问键对应的值map[key]时:若该key存在,则访问取得value值;若该原创 2021-04-15 22:20:09 · 7766 阅读 · 0 评论 -
map.find与string.find的返回值差别
1、map.find与std::find的返回值:unordered_map<int, int> mymap; mymap.insert({1,2}); auto it = mymap.find(1); // 返回值为迭代器 if (it != mymap.end()) { // 不存在返回尾迭代器mymap.end() cout << it->first << it->second <<原创 2021-04-15 22:16:36 · 2817 阅读 · 0 评论 -
map中key值自定义排序的常用方式
1、代码示例: 关注注释// 模板为stl库提供 template <class T> struct less { bool operator() (const T& x, const T& y) const {return x<y;} }; #include <map> #include <utility> #include <iostream> using namespace std; //原创 2021-04-09 22:09:08 · 702 阅读 · 0 评论 -
std::numeric_limits使用
1、介绍:提供关于不同平台编译的算术类型(整型、浮点型)的属性信息,如int型的最大最小值,位宽等信息。 因此该模板素有成员函数、成员变量均为静态函数。2、使用:#include <iostream> // std::cout#include <limits> // std::numeric_limitsint main () { std::cout << std::boolalpha; std::cout << "M原创 2021-03-31 20:56:50 · 635 阅读 · 0 评论 -
string转不同进制数、十进制数转不同进制字符串
1、str转不同进制数:1.1、strtolint main() { string abc = "01011101"; long num_two_radix = strtol(abc.c_str(), nullptr, 2); cout << num_two_radix << endl; // num_two_radix = 93; num_two_radix = 0b01011101; long num_ten_radix原创 2021-03-31 20:49:00 · 542 阅读 · 0 评论 -
std::stringstream使用:用于传输字符串流
总结:1、用于传输字符串流,知道数据格式则能解析。2、stringstream::str将流中数据转换成string字符串。3、<<与>>填入与取出流中数据。1、各成员函数作用:1.1、重载的<<与>>运算符:std::stringstream ss; ss << 100 << ' ' << 200; int foo,bar; ss >> foo >> bar; 1.2原创 2021-02-21 12:43:37 · 3046 阅读 · 0 评论 -
C++11特性用法:原子操作
原子操作:是说其在执行过程中是不可能被其它线程打断的,像C++中的std::atomic修饰过的变量,对这类变量的操作无需传统的加锁保护,因为C++会确保在变量的修改过程中不会被打断。1、std::atomic应用:防止多线程数据竞争说明:Objects of atomic types contain a value of a particular type (T). The main characteristic of atomic objects is that access to this co原创 2021-02-21 12:36:10 · 1537 阅读 · 2 评论 -
std::thread用法:创建、挂起、唤醒线程;线程ID转int
1、线程常见用法:// thread example#include <iostream> // std::cout#include <thread> // std::thread void foo() { // do stuff... }void bar(int x) { // do stuff... }int main() { std::thread first (foo); // spawn new thread th原创 2021-02-21 12:34:10 · 2494 阅读 · 0 评论 -
lambda表达式(匿名函数)基本用法
总结:1、lambda表达式的捕获类型见下详述。2、返回类型(可以自动推导、可以省略)。3、捕获的参数可以在函数体中使用。1、基础概念:C++在C11标准中引入了匿名函数,即没有名字的临时函数,又称之为lambda表达式。lambda表达式实质上是创建一个匿名函数/对象。2、用法介绍:Lambda(匿名函数)的基本语法:auto func = [capture] (params) opt -> ret { func_body; };其中func是可以当作lambda表达式的名字,作原创 2021-02-18 21:21:50 · 1314 阅读 · 0 评论 -
std::tuple、std::tie(可用于结构体大小比较)、std::pair用法
1、tuple应用:解释:是一个元组,可包含无限多不同类型变量,pair的升级版,但没有pair得成员变量first、second。1.1、代码:// tuple example#include <iostream> // std::cout#include <tuple> // std::tuple, std::get, std::tie, std::ignoreint main (){ std::tuple<int,char>原创 2021-01-31 22:17:55 · 2101 阅读 · 0 评论 -
C11特性:std::equal_range、std::lower_bound、std::min_element、获取迭代器在容器中的位置序号、std::distance
1、std::equal_range:原型: template <class ForwardIterator, class T, class Compare> pair<ForwardIterator,ForwardIterator> equal_range (ForwardIterator first, ForwardIterator last, const T& val, Compare comp); 用法: 在一个已经排序的容器中查找等于指定元素的子序列,返原创 2021-01-31 21:48:47 · 631 阅读 · 0 评论 -
std::function的用法
介绍:std::function是一个可调用对象包装器,是一个类模板,可以容纳所有可调用对象,它可以用统一的方式处理函数、函数对象、函数指针,并允许保存和延迟它们的执行。 头文件:#include 定义格式:std::function<函数类型> 因为std::function是一种模板,所以要传入类型,将其当做std::vector<>这样的模板,像std::vector传入类型int一样,std::function传入的是函数类型<返回值 (参数类型)>,如原创 2021-01-31 20:43:43 · 5103 阅读 · 2 评论 -
std::bind:将可调用对象和其参数绑定成一个防函数
介绍:可将std::bind函数看作一个通用的函数适配器,它接受一个可调用对象,生成一个新的可调用对象来“适应”原对象的参数列表。std::bind将可调用对象与其参数一起进行绑定,绑定后的结果可以使用std::function保存。作用:将可调用对象和其参数绑定成一个防函数;只绑定部分参数,减少可调用对象传入的参数(可用lambda匿名函数包裹原函数时传入参数代替)。代码示例:1、std::bind绑定普通函数double my_divide (double x, double y) {原创 2021-01-24 21:12:35 · 215 阅读 · 0 评论 -
一个类中的定义类型如何在其他类中使用,如map::value_type
总结:1、与调用名称空间下的类型一样,使用作用域运算符::调用其他类中定义的类型。2、map的新插入方式:my_map.insert(map::value_type(1, 1.2));1、我们使用名称空间下的类型方法如下:std::map mymap; // 调用std名称空间下的map类型。 2、如何使用类中定义的类型呢?在别的类中要用#include 来导入这个类A;与调用名称空间下的类型一样,使用作用域运算符::调用。代码:class A { typ原创 2021-01-24 20:45:52 · 844 阅读 · 0 评论 -
C++互斥对象std::mutex与std::shared_mutex;互斥锁:std::lock_guard、std::unique_lock与std::shared_lock的应用
1、std::mutex(互斥对象)简单的信号量,不支持递归原理:A mutex is a lockable object that is designed to signal when critical sections of code need exclusive access, preventing other threads with the same protection from executing concurrently and access the same memory locati原创 2021-01-23 15:29:04 · 5675 阅读 · 1 评论 -
STL标准库常用语法:hash函数、find_if、count_if、string.find、std::atomic
1、hash函数的应用:根据入参hash出一个唯一的hash id原型:hash函数对象类:用法像函数的对象,看注释std::hash<std::string> str_hash; // 定义一个对象 size_t res3 = str_hash(str1); // 调用该对象的括号运算符()函数 代码:#include <functional> #include <string> int main() { char nts1[]原创 2020-11-08 00:37:05 · 1574 阅读 · 0 评论 -
STL标准库常用语法:numeric_limits、std::map::swap、std::array::data、std::move
1、利用numeric_limits将变量初始化为无效值#include <limits> int val = std::numeric_limits<int>::max(); 利用这个库函数将val变量初始化为int的最大值(最大值作为无效值)。2、std::map::swap交换两个变量函数原型:void swap (map& x); std::map<char,int> foo,bar; foo.swap(bar); 原理:只是交换指针,原创 2020-11-08 00:35:56 · 848 阅读 · 0 评论 -
【类型转换】C++中char、char*、int、string相互转换函数及string转不同进制数函数
1、char转int与int转char1.1、char转int:char a = '1';int b = a - '0'; // b = 1;1.2、int转char:int a = 1;char b = a + '0'; // b = '1';2、char星、char转string与strng转char星、char2.1、char星、char转string:char* ptr = "abcd";string s(ptr); // s = "abcd";char c = 'a';原创 2020-07-11 23:53:08 · 30381 阅读 · 1 评论 -
C++中常用的字符char判断与字符串string处理函数:isalnum、reverse、compare,+=
1、常用的字符char判断函数:1.1、isalnum函数相当于:if(s[i]<'0' || (s[i]>'9'&& s[i]<'a') || s[i]>'z'){ return false;}else{ return true;2、常用的字符串string处理函数:2.1、compare比较函数:相同返回0,不同返回<0或>0。std::string str1 ("green apple");std::string str原创 2020-06-19 21:11:47 · 1580 阅读 · 0 评论 -
transform模板函数调用tolower函数报错原因、解决办法
1、报错现象:1.1、执行的代码:string s = "Abcd. ,,cD";transform(s.begin(), s.end(), s.begin(), tolower);tolower作用:是大写字母则转换为小写,不是字母则保持不动。1.2、提示的错误:Line 5: Char 9: fatal error: no matching function for call to 'transform' transform(s.begin(), s.end(), s.be原创 2020-06-19 20:30:29 · 1659 阅读 · 0 评论 -
STL自定义排序函数:sort()函数;priority_queue,set,map等容器排序函数
1、sort()函数自定义排序:1.1、sort()模板原型:1.1.1、默认模板:利用<比较,升序排列template <class_Randlt> // 模板参数为迭代器类型void sort(_Randlt first, _RandIt last); // 参数为起止随机访问迭代器前提是a、b (_Randlt迭代器指向的对象) 必须可比较大小。元素比较大小是用<进行的,如果表达式a<b的值为 true,则 a 排在 b 前面。a,b为值对象:可直接比较大原创 2020-06-11 20:09:36 · 1317 阅读 · 1 评论 -
STL中常用的技巧:set检查重复、优先队列排序、string大小写、min三个数取最小、map建立映射、pair应用
1、检查是否有重复:set<int> s;s.insert(2);if(s.count(2) == 0){...} // s.count()统计个数2、插入元素自动排序:priority_queue<int> ans // 最大堆排序priority_queue<long,vector<long>, greater<long>> ans; // 最小堆排序3、string字符串大小写转换:string s;transform(原创 2020-05-31 11:26:44 · 396 阅读 · 0 评论 -
vector、array、valarray区别、STL中sort函数
1、指针是一种特殊的迭代器,因此copy()等STL函数可用于常规数组,STL对象也可用常规数组指针区间进行初始化。2、有些STL算法,接受一个函数对象参数,使用其来处理数据。如:bool funca(const vec_val& a,const vec_val& b){...}sort(vec.begin(),vec.end(),funca);funca为函数对象参数,...原创 2020-03-09 18:28:26 · 378 阅读 · 0 评论 -
STL库中迭代器、for_each()函数用法
1、迭代器iternator:广义指针。vector<double>::iternator ptr;begin():返回指向容器中第一个元素的迭代器。end():返回指向超过容器尾的迭代器。使用超过容器尾的迭代器ptr!=abc.end()更方便遍历。vector<double> abc = {12,23,44,55,66};for(ptr = abc.beg...原创 2020-03-08 17:57:15 · 510 阅读 · 1 评论 -
容器中的find成员函数与algorithm库中的find方法
1、find成员函数string、map、set等容器有find成员函数,因此可以直接用来查找容器中的成员。map<int,int> myMap;myMap[1] = 3;myMap[4] = 6;auto ptr = myMap.find(1);if(ptr == myMap.end()){ cout<<"容器中不存在键为1的元素"}2、find库方法:list、vector等容器没有find成员函数,因此必须借助algorithm库中的find方法查找容器中原创 2020-06-04 18:55:35 · 639 阅读 · 0 评论 -
C++中substr()与java中substring()函数区分
注:C++中只有一个子字符串的操作函数:s.substr();没有s.substring()函数,s.substring()是java里的。Java和C++中都有关于子字符串的操作,C++中是substr(),Java中是substring(),两者的用法上稍有些区别。1、首先针对只有一个参数的情况:s.substr(start) 和 s.substring(start) 均表示从start位置开始到结尾的子字符串。2、对于有两个参数的情况:二者就存在区别:C++: substr(start转载 2020-06-09 20:04:50 · 719 阅读 · 0 评论