c->c++(三):stl

本文主要探讨c++的stl相关知识:模版,容器,泛型算法,萃取特化,智能指针等。

模版 模板typename和class均可定义

模板参数可是类型,还可是值

模板编译根据调用实参类型推导参数类型

编译器用值的类型实例化模板,用指针类型实例化模板,去除const修饰

float,class-type类型对象,内链接对象作为非类型模板参数

容器 容器类=数据结构 + 算法

序列容器:位置与元素值无关:array、vector、deque、list、forward_list

关联容器:数据插入时自动从小到大排列:set、multiset、map、mutilmap

无序关联容器:元素未排序的:unordered_set,unordered_mapunordered_multiset,unordered_multimap

array:固定数组,可随机访问,不能添加或删除元素

vector:可变数组,可随机访问,尾部外位置插入或删除元素慢

string:存储字符,可随机访问,尾部插入或删除快(大小可变)

deque:双端队列,可随机访问,头尾插入或删除快

forward_list:单链表,可单顺序访问,任何位置插入或删除快

list:双向链表,可双向顺序访问,任何位置插入或删除快

set:有序容器,元素在集合中是唯一,用红黑树实现,插入、删除和查找时间复杂度为(log n)

map:有序键值对容器,键在 map 中是唯一且键值唯一,用红黑树实现,插入、删除和查找操时间复杂度为(log n)

multimap:关键字可重复出现的map

multiset:关键字可重复出现的set

arry array是固定大小数组容器,默认构造非空

长度为零时array.begin() == array.end(),拥有唯一值,front()和back()未定义

swap时迭代器指向同一array元素并将改变元素的值

begin()返回首元素迭代器,end()返回尾元素迭代器,rbegin()返回尾元素逆向迭代器,rend()返回首元素逆向迭代器,cbegin()同begin(),cend()同end(),crbegin()同rbegin(),crend()同rend(),增加了 const 属性

size()返回当前元素数量(N)同max_size(),empty()判断容器是否为空

at(n)返回元素n引用且检查越界抛出异常out_of_range,front()返回首元素引用,back()返回末尾元素引用,data()返回首元素指针

fill(n)设置每个元素值为n,m.swap(n)交换m和n中所有元素(长度和类型相同),swap(m,n)交换m和n中所有元素

operator==检查是否有相同数量元素且同位置元素是否相等

重载get()全局函数访问容器指定元素并返回引用

Vector 动态数组序列容器,元素连续存储可通过迭代器和指针访问元素

assign()替换容器中的内容

max_size()返回理论上的最大值

reserve()修改容器容量

capacity()返回当前分配的存储容量

shrink_to_fit()清除未使用的容量

clear()清除所有元素

insert()指定位置插入元素,返回插首元素的迭代器

emplace()在位置前插入元素,返回插入元素的迭代器

erase()清除指定的元素

push_back()追加元素到容器尾部

emplace_back()在容器末尾构造元素(调用构造函数)

pop_bak()移除末尾元素

resize()改变元素大小

string operator=初始化字符串

c_str返回c风格的字符串

size(),length()字符串大小

append(),operator+=追加的字符串尾部

replace()替换字符串

find()查找字符串

find_first_of()寻找字符首次出现的位置,找到返回字符位置,找不到返回npos

find_last_of()寻找字符最后次出现的位置

find_first_not_of()寻找字符首次丢失的位置

find_last_not_of()寻找字符最后丢失的位置

stoi,stol,stoll转换字符串为有符号整数

stoul,stoull转换字符串为无符号整数

stof,stod,stold转换字符串为浮点值

to_string转换整数或浮点值为string

to_wstring转换整数或浮点值为wstring

deque 有索引序列容器,允许首尾插入及删除

与vector相反,deque元素不连续,按需扩张

push_front()前附给定元素到容器起始

emplace_front()在容器起始构造元素(调用构造函数)

pop_front()移除容器首元素

forward_list 单链表,任何位置插入和移除元素,不支持随机访问

before_begin(),cbefore_begin()返回指向首元素前一元素迭代器,此元素表现为占位符,试图访问会导致未定义行为

insert_after()在位置元素后插入

emplace_after()在容器末尾构造元素(调用构造函数)

erase_after()从容器移除指定元素

merge()链表合并,other与this指一对象时没有操作,被合并链表为空

splice_after()从另一forward_list移动元素到*this,元素插入指向元素后,被移动元素的链表缺少该元素

remove(),remove_if()移除所有满足标准元素,只有指向被移除元素迭代器和引用会失效

reserve()逆转元素顺序,迭代器和引用不会失效

unique()删除连续重复元素

sort()排序元素(升序),不会导致迭代器和引用失效

list带头双向循环链表,任意位置进行插入和删除,不支持[]随机访问

set 关联容器,含有Key类型对象排序集

count()返回有key元素数(0,1)

find()寻找键key元素,返回值指向元素迭代器,未找到则返回尾后迭代器

contains()检查容器是否有key

equal_range()返回键元素范围,范围有两个迭代器(该元素迭代器以及下一元素迭代器)

lower_bound()返回指向首个>=key 元素迭代器

upper_bound()返回指向首个<=key 元素迭代器

map 有序关联容器,包含具有唯一键键值对,map实现为红黑树

insert_or_assign() key存在则赋值给当前key,不存在则建立key在赋值

emplace_hint()向容器中尽可能接近紧接元素之前的位置插入新元素

multiset: Key类型对象有序集,允许多个Key有相同值
**multimap:**关联容器,键值对已排序列表,多个元素可拥有同一键

unordered_set 无序关联容器

bucket_count()返回容器中的桶数

max_bucket_count()返回容器最大桶数

bucket_size()返回桶中的元素数

bucket()返回键key桶索引

load_factor()返回平均每桶元素数即size()/bucket_count()

max_load_factor()管理最大加载因子(每个桶的平均元素数),加载因子超出阈值,增加桶数,返回最大加载因子

rehash()设置桶数为不小于count且>=size()/max_load_factor()

reserve()设置桶数至少count个元素且不超出最大加载因子

unordered_map: 无序关联容器,有带唯一键的键值对
unordered_multiset: 键的集合,按照键生成散列
unordered_multimap: 键值对的集合,按照键生成散列
stack: 适配一个容器以提供栈
queue: 适配一个容器以提供队列
priority_queue: 适配一个容器以提供优先级队列
flat_set: 调整容器以提供按键排序的唯一键集合
flat_map: 适配两个容器以提供按唯一键排序的键值对集合
flat_multiset: 调整容器以提供按关键字排序的关键字集合
flat_multimap: 适配两个容器以提供按键排序的键值对集合
span: 连续的对象序列上的无所有权视图
**mdspan:**多维非拥有数组视图

泛型算法 容器是数据封装,泛型算法是数据操作方法

谓词函数,数据操作函数:函数,函数指针,lambda,函数对象

lambda:[捕获] (传参) mutable或exception声明 ->返回类型 {}

最简lambda:[](){},调用:[](){}();

lambda捕获列表

\]:不捕获 \[=\]值捕获包括所在类的this \[\&\]引用捕获包括所在类this \[this\]捕获所在类this \[a\]值捕获a \[\&a\]引用捕获a \[a,\&b\]值捕获a,引用捕获b \[=,\&a,\&b\]引用捕获a和b其余值捕获 \[\&,a,b\]值捕获a和b其余引用捕获 **不修改序列操作** for_each(first,last,fun)对范围\[first,last)中迭代器解引用传给函数对象fun all_of(first,last,fun)对范围\[first,last)中迭代器解引用传给函数对象fun,所有元素满足func返回true none_of(first,last,fun)对范围\[first,last)中迭代器解引用传给函数对象fun,所有元素不满足func返回true any_of(first,last,fun)对范围\[first,last)中迭代器解引用传给函数对象fun,有元素满足func返回true find(first,last,num)对范围\[first,last)中迭代器解引用传给函数对象fun,有元素等于num返回该元素迭代器 find_if(first,last,fun)对范围\[first,last)中迭代器解引用传给函数对象fun,有元素满足fun返回该元素迭代器 find_if_not(first,last,fun)对范围\[first,last)中迭代器解引用传给函数对象fun,有元素不满足fun返回该元素迭代器 find_end(first,last,f,l,fun)在范围\[first, last)中搜索范围\[f,s)经过fun处理元素迭代器 find_first_of(first,last,f,l,fun)在范围 \[first, last)中搜索范围\[f,l)经过fun处理元素,返回搜索到的第一个元素迭代器 count/count_if(first,last,fun/num)返回范围\[first, last中满足fun/num元素数 mismatch(first,last,f,l)返回两个范围内首次出现不同的元素 search(first,last,f,l,fun)在范围 \[first, last)中搜索范围\[f,l)经过fun处理元素,返回搜索到的第一个元素迭代器 serach_n在范围\[first,last,count,value,fun)中搜索count个等同元素的序列,每个都等于给定的值 value,fun(\*first,value),返回搜索到的第一个元素迭代器 **修改序列的操作** copy(first,last,f)/copy_if(first,last,f,fun)复制范围\[first, last)中的元素到从f开始的另一范围,返回目标最后下一个元素输出迭代器 copy_n(frist,num,f)从first开始复制num个元素到f开始的地方,返回目标最后下一个元素输出迭代器否则返回f copy_backward(first,last,l)复制范围\[first, last)中的元素到范围尾部(l为尾部迭代器),返回最后复制的元素 move(first,last,f)复制范围\[first, last)中的元素到从f开始的另一范围,返回目标最后下一个元素输出迭代器 move_bakcward(first,last,l)复制范围\[first, last)中的元素到范围尾部(l为尾部迭代器),返回最后复制的元素 swap(a,b)交换a,b,iter_swap(a,b)交换两个迭代器指向的元素 swap_ranges(first,last,f)交换范围\[first,last)中的元素到从f开始的另一范围 replace(first,last,old,new)/replace_if(first,last,fun,new)替换来自范围\[first, last)的元素到始于f范围,复制过程中以new(fun(\*first))替换所有满足特定判别标准的元素 replace_copy_if(first,last,f,fun,new)复制来自范围\[first, last)的元素到始于f范围,复制过程中以new(fun(\*first)) 替换所有满足特定判别标准的元素 fill(first,last,num)用num填充范围\[first, last)的元素 fill(first,count,num)用num填充起始范围first的count个元素值为num generate(first,last,fun)将fun产生的数赋值给\[first, last)的元素 generate(first,count,fun)将fun产生的数赋值给first起始的count个元素 remove(first,last,value)/remove_if(first,last,fun)移除范围内value或fun返回值 remove_copy(first,last,f,value)/remove_copy_if(first,last,f,fun)复制范围内的元素到f,并移除value或fun返回值 unique_copy(first, last,f)从范围\[first, last)复制元素到从f开始的另一范围,使得目标范围不存在连续的相等元素 reverse(first, last)/reverse_copy(first, last,f)反序 rotate_copy(first,n_f,last,f)从范围\[first, last)复制元素到始于f的另一范围,使得 \*n_f成为新范围的首元素而 \*(n_f-1)为末元素 **排序操作** sort将范围按升序排序 stable_sort将范围内的元素排序,同时保持相等的元素之间的顺序 partial_sort排序一个范围的前 N 个元素 partial_sort_copy对范围内的元素进行复制并部分排序 is_sorted检查范围是否已按升序排列 is_sorted_until找出最大的有序子范围 nth_element将给定的范围部分排序,确保其按给定元素划分 **二分搜索操作** lower_bound返回指向第一个不小于给定值的元素的迭代器 upper_bound返回指向第一个大于给定值的元素的迭代器 equal_range返回匹配特定键值的元素范围 binary_search确定元素是否存在于某部分有序的范围中 **集合操作** includes若一个序列是另一个的子序列则返回 true set_union计算两个集合的并集 set_intersection计算两个集合的交集 set_difference计算两个集合的差集 set_symmetric_difference计算两个集合的对称差 **归并操作** merge合并两个有序范围 inplace_merge就地合并两个有序范围 **堆操作** push_heap将一个元素加入到一个最大堆 pop_heap从最大堆中移除最大元素 make_heap从一个元素范围创建出一个最大堆 sort_heap将一个最大堆变成一个按升序排序的元素范围 is_heap检查给定范围是否为一个最大堆 is_heap_until查找能成为最大堆的最大子范围 **最小/最大操作** max返回各给定值中的较大者 max_element返回范围内的最大元素 min返回各给定值中的较小者 min_element返回范围内的最小元素 minmax返回两个元素的较小和较大者 minmax_element返回范围内的最小元素和最大元素 **萃取和特化** 模板特化类似函数重载,编译链接时确定 优先级:同名函数\>全特化\>偏特化\>泛化 全特化所有模板类型为具体类型 偏特化部分特化原模板的类型 区分T是源生类型或自定义类型 POD(原生类型)int、double,char,float等,本质是没有高级特征(构造析构,虚函数等) POD memcpy可用,非POD类型需循环拷贝 is_pod判断是否是pod类型 **智能指针** 智能指针本身是类 智能指针解决内存泄漏问题,连带自动释放内存 智能指针本质原理:利用对象释放时会自动调用析构函数特性 unique_ptr对象不可复制(=),可移动(move) unique_ptr同时间只指向一个对象,指向新对象时,之前对象被释放 unique_ptr本身被释放时,对象也释放 unique_ptr不能进行赋值和拷贝构造 release()释放被管理对象的所有权,返回被管理对象指针,无被管理对象返回nullptr reset(对象)替换被管理对象,若旧对象为非空则调用删除器删除 swap()交换被管理对象和关联删除器 get()返回被管理对象指针,无对象返回nullptr get_deleter()返回会用于析构被管理对象的删除器对象 shared_ptr基于引用计数设计,多个智能指针绑定1个对象 shared_ptr使用构造函数或make_shared方法构造 shared_ptr释放指针对象,调用Deleter,再调析构释放 use_count()管理当前对象的shared_ptr实例数量 unique()管理当前对象的shared_ptr实例数量为1(use_count() = 1)返回true否则false make_shared()创建管理一个新对象的共享指针 weak_ptr不管理shared_ptr内部指针,没有\*和-\>操作符 weak_ptr不共享指针,不操作资源,构造和析构不影响引用计数 weak_ptr监视shared_ptr中管理资源是否存在 expired()管理对象删除为true否则为false(use_count() = 0) lock()若无共享对象返回false,否则返回shared_ptr对象 reset()释放被管理对象的所有权(use_count() = 0) **demo1:** **模版** **目录:** ![](https://i-blog.csdnimg.cn/direct/d3635b66aa3c4de5812cf8e8b4f4cb85.png) **run.sh** #!/bin/bash if [ -f ./Makefile ] then make clean fi cmake . make echo "---------------------------------" ./pro **clean.sh** #!/bin/bash rm -rf CMakeFiles pro Makefile CMakeCache.txt cmake_install.cmake **check_mem.sh** valgrind --tool=memcheck --leak-check=full --show-reachable=yes --trace-children=yes -s ./pro **CMakeLists.txt** CMAKE_MINIMUM_REQUIRED(VERSION 2.20) #最低版本要求 SET(CMAKE_CXX_COMPILER "g++-11") #设置g++编译器 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g") #添加编译选项 PROJECT(CLASS) #设置工程名 MESSAGE(STATUS "template test") #打印消息 ADD_EXECUTABLE(pro main.cpp) #生成可执行文件 **main.cpp** #include using namespace std; template class Person { private: T1 argv1; T2 argv2; public: Person(){}; Person(T1 argv1,T2 argv2); void printf_info(); void operator+=(Person p); template friend Person operator+(Person p1,Person p2); }; template class Man:public Person { public: T1 argv1; T2 argv2; Man(T1 argv1,T2 argv2):Person(argv1,argv2),argv1(argv1),argv2(argv2){}; }; template Person::Person(T1 argv1,T2 argv2) { this->argv1 = argv1; this->argv2 = argv2; } template class Arry { private: X ar[ARRY_SIZE] = {0}; public: void set_arry(); void printf_arry(); }; template void Person::printf_info() { string s = typeid(this->argv1).name(); if(s == "i") { cout << "name :" << this->argv2 << endl; cout << "age :" << this->argv1 << endl; } else { cout << "name :" << this->argv1 << endl; cout << "age :" << this->argv2 << endl; } } template void Person::operator+=(Person p) { this->argv1 += p.argv1; this->argv2 += p.argv2; } template Person operator+(Person p1,Person p2) { Person tmp; tmp.argv1 = p1.argv1 + p2.argv1; tmp.argv2 = p1.argv2 + p2.argv2; return tmp; } template void Arry::set_arry() { for(int i = 0;i < ARRY_SIZE ;i++) ar[i] = i; } template void Arry::printf_arry() { for(int i = 0;i < ARRY_SIZE ;i++) cout << ar[i] << " "; cout << endl; } int main() { Person p1(10,"hello"); Person p2(10," word"); Person p3 = p1 + p2; Person p4(10,"!"); p3 += p4, p3.printf_info(); Man m(20,"xiaoming"); m.printf_info(); m.Person::printf_info(); Arry a; a.set_arry(); a.printf_arry(); return 0; } **结果示例:** ![](https://i-blog.csdnimg.cn/direct/82670f9fae95469b80e4a741ad6cdb21.png) **demo2:** **string** **目录:** ![](https://i-blog.csdnimg.cn/direct/881daa3fa1ca4621968466b78df82f5c.png) **run.sh** #!/bin/bash if [ -f ./Makefile ] then make clean fi cmake . make echo "---------------------------------" ./pro **check_mem.sh** valgrind --tool=memcheck --leak-check=full --show-reachable=yes --trace-children=yes -s ./pro **clean.sh** #!/bin/bash rm -rf CMakeFiles pro Makefile CMakeCache.txt cmake_install.cmake **CMakeLists.txt** CMAKE_MINIMUM_REQUIRED(VERSION 2.20) #最低版本要求 SET(CMAKE_CXX_COMPILER "g++-11") #设置g++编译器 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g") #添加编译选项 PROJECT(CLASS) #设置工程名 MESSAGE(STATUS "string test") #打印消息 ADD_EXECUTABLE(pro main.cpp) #生成可执行文件 **main.cpp** #include #include using namespace std; int main() { string s = "hello word"; cout << "s.size():" << s.size() << endl; cout << "s.length():" << s.length() << endl; s += "!!!"; cout << "s:" << s << endl; const char *p = s.c_str(); printf("s:%s\n",p); auto f = s.find('w'); s.replace(f,4,"cxb"); cout << "s:" << s << endl; if (s.find_first_of('u') == string::npos) cout << "s have no 'u'" << endl; string str = s.substr(0,5); cout << "str:" << str << endl; string name; getline(cin,name); cout << "name:" << name << endl; int n = stoi("100"); cout << "n(int):" << n << endl; string num = to_string(n); cout << "num(string):" << num << endl; return 0; } **结果示例:** ![](https://i-blog.csdnimg.cn/direct/887c389337ba43948dffde94a89b0789.png) **demo3:** **容器** **目录:** ![](https://i-blog.csdnimg.cn/direct/633b959b027041d1b9c2b73a938c8386.png) **run.sh** #!/bin/bash if [ -f ./Makefile ] then make clean fi cmake . make echo "---------------------------------" ./pro **check_mem.sh** valgrind --tool=memcheck --leak-check=full --show-reachable=yes --trace-children=yes -s ./pro **clean.sh** #!/bin/bash rm -rf CMakeFiles pro Makefile CMakeCache.txt cmake_install.cmake **CMakeLists.txt** CMAKE_MINIMUM_REQUIRED(VERSION 2.20) #最低版本要求 SET(CMAKE_CXX_COMPILER "g++-11") #设置g++编译器 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g") #添加编译选项 PROJECT(CLASS) #设置工程名 MESSAGE(STATUS "stl test") #打印消息 set(SRC_LIST main.cpp array.cpp vector.cpp deque.cpp forward_list.cpp list.cpp set.cpp map.cpp unordered_set.cpp stack.cpp queue.cpp priority_queue.cpp unordered_multimap.cpp) ADD_EXECUTABLE(pro ${SRC_LIST}) #生成可执行文件 **main.cpp** #include #include "main.hpp" using namespace std; int main() { cout << "----------------------stl_array---------------------" << endl; stl_array(); cout << "----------------------stl_vector--------------------" << endl; stl_vector(); cout << "----------------------stl_deque---------------------" << endl; stl_deque(); cout << "----------------------stl_forward_list--------------" << endl; stl_forward_list(); cout << "----------------------stl_list----------------------" << endl; stl_list(); cout << "----------------------stl_set-----------------------" << endl; stl_set(); cout << "----------------------stl_map-----------------------" << endl; stl_map(); cout << "----------------------stl_unordered_set-------------" << endl; stl_unordered_set(); cout << "----------------------stl_stack---------------------" << endl; stl_stack(); cout << "----------------------stl_queue---------------------" << endl; stl_queue(); cout << "----------------------stl_priority_queue------------" << endl; stl_priority_queue(); cout << "----------------------stl_unordered_multimap--------" << endl; stl_unordered_multimap(); return 0; } **main.hpp** #ifndef __MAIN_HPP #define __MAIN_HPP void stl_array(); void stl_vector(); void stl_deque(); void stl_forward_list(); void stl_list(); void stl_set(); void stl_map(); void stl_unordered_set(); void stl_stack(); void stl_queue(); void stl_priority_queue(); void stl_unordered_multimap(); #endif **array.cpp** #include #include using namespace std; void stl_array() { array a1 = {1,2,3}; array a2; array a3; a2 = a1; cout << "a2.front:" << a2.front() << endl; cout << "a2[2]:" << a2[1] << endl; cout << "get<2>(a2):" << get<2>(a2) << endl; cout << "a2.back:" << a2.back() << endl; cout << "*(a2.data):" << *(a2.data()) << endl; cout << "a2.empty():" << boolalpha << a2.empty() << endl; cout << "a2.size():" << a2.size() << endl; cout << "a2.max_size():" << a2.max_size() << endl; cout << "a3.empty():" << boolalpha << a3.empty() << endl; cout << "a3.size():" << a3.size() << endl; cout << "a3.max_size():" << a3.max_size() << endl; cout << "a1:"; for(auto i = a1.begin();i != a1.end();i++) { cout << *i << " "; } cout << endl; cout << "a2:"; for(auto i = 0;i < a2.size();i++) { cout << a2.at(i) << " "; } cout << endl; cout << "a2 reserve:"; for(auto i = a2.rbegin();i != a2.rend();i++) { cout << *i << " "; } cout << endl; a3.fill(6); cout << "a3:"; for(auto i = 0;i < a3.size();i++) { cout << a3.at(i) << " "; } cout << endl; cout << "swap a1 a3 : " << endl; a3.swap(a1); cout << "a3:"; for(auto i = 0;i < a3.size();i++) { cout << a3.at(i) << " "; } cout << endl; cout << "a1:"; for(auto i = a1.begin();i != a1.end();i++) { cout << *i << " "; } cout << endl; } **deque.cpp** #include #include using namespace std; template static void printf_queue(T const& q) { for(auto i : q) cout << i << " "; cout << endl; } void stl_deque() { deque num; num.push_front(1); num.push_front(2); num.push_front(3); num.emplace_front(4); num.emplace_front(5); num.emplace_front(6); cout << "num:"; printf_queue(num); cout << "pop_front num:"; num.pop_front(); printf_queue(num); } **forward_list.cpp** #include #include using namespace std; template static void printf_forward_list(T const& n) { for(auto i : n) cout << i << " "; cout << endl; } void stl_forward_list() { forward_list num; forward_list tmp = {7,8,9,10}; forward_list num1 = {7,8,9,10}; num.insert_after(num.before_begin(),1); num.insert_after(num.before_begin(),2); num.insert_after(num.before_begin(),3); cout << "insert_after num:" << endl; printf_forward_list(num); cout << "emplace_after num:"; num.emplace_after(num.before_begin(),4); num.emplace_after(num.before_begin(),5); num.emplace_after(num.before_begin(),6); printf_forward_list(num); cout << "tmp:"; printf_forward_list(tmp); cout << "num.splice_after(num.before_begin(),tmp)" << endl; num.splice_after(num.before_begin(),tmp); cout << "tmp :"; printf_forward_list(tmp); cout << "num :"; printf_forward_list(num); cout << "num1:"; printf_forward_list(num1); cout << "num.merge(num1)" << endl; num.merge(num1); cout << "num1:"; printf_forward_list(num1); cout << "num:"; printf_forward_list(num); cout << "sort num:"; num.sort(); printf_forward_list(num); cout << "unique num:"; num.unique(); printf_forward_list(num); cout << "reverse num:"; num.reverse(); printf_forward_list(num); cout << "remove num:"; num.remove(10); printf_forward_list(num); cout << "erase_after num:"; num.erase_after(num.before_begin()); printf_forward_list(num); cout << "num.erase_after(fi,la):"; auto fi = next(num.begin()); auto la = next(fi, 3); cout << "fi:" << *(fi) << endl; cout << "la:" << *(la) << endl; num.erase_after(fi,la); printf_forward_list(num); } **list.cpp** #include #include using namespace std; template static void printf_list(T const& l) { for(auto i : l) cout << i << " "; cout << endl; } void stl_list() { list num; num.push_front(1); num.push_front(2); num.push_front(3); num.emplace_front(4); num.emplace_front(5); num.emplace_front(6); cout << "num:"; printf_list(num); cout << "pop_front num:"; num.pop_front(); printf_list(num); } **map.cpp** #include #include using namespace std; template static void printf_map(T const& m) { for(auto [key,value] : m) cout << key << ":" << value << endl ; } void stl_map() { map m = {{"name","xiaoming"},{"income","100"}}; m.insert(m.begin(),{"age","20"}); cout << "map:" << endl; printf_map(m); m.insert_or_assign("saving_count","2000"); m.insert_or_assign("income","1000"); auto tmp = m.find("name"); m.emplace_hint(tmp,"hobby","game"); cout << "new map:" << endl; printf_map(m); } **priority_queue.cpp** #include #include using namespace std; void stl_priority_queue() { priority_queue p; p.push(1); p.push(8); p.push(5); p.push(3); p.push(2); cout << "priority_queue:"; while(p.size()) { cout << p.top() << " "; p.pop(); } cout << endl; } **queue.cpp** #include #include using namespace std; void stl_queue() { queue q; q.push("linux"); q.push("windows"); q.push("macos"); q.push("android"); q.push("harmonyos"); cout << "queue front :" << q.front() << endl; cout << "queue back :" << q.back() << endl; cout << "queue :"; while(!q.empty()) { cout << q.front() << " "; q.pop(); } cout << endl; } **set.cpp** #include #include using namespace std; template static void printf_set(T const& s) { for(auto i : s) cout << i << " "; cout << endl; } void stl_set() { set s; s.insert(s.begin(),1); s.insert(s.begin(),1); s.insert(s.begin(),1); s.insert(s.begin(),2); s.insert(s.begin(),3); cout << "set :" ; printf_set(s); if(s.count(1)) cout << "set has 1 :" << s.count(1) << endl; auto tmp = s.find(2); if(tmp != s.end()) cout << "set has 2" << endl; auto [b,e] = s.equal_range(2); cout << "b = s.equal_range(2):" << *b << endl; cout << "e = s.equal_range(2):" << *e << endl; cout << "s.lower_bound():" << *(s.lower_bound(2)) << endl; cout << "s.upper_bound():" << *(s.upper_bound(2)) << endl; } **stack.cpp** #include #include using namespace std; void stl_stack() { stack s; s.push(1); s.push(2); s.push(3); s.push(4); s.push(5); cout << "stack :"; while(s.size() != 0) { cout << s.top() << " "; s.pop(); } cout << endl; } **unordered_multimap.cpp** #include #include using namespace std; template static void print_unordered_multimap(T const& p) { for(auto i : p) { cout << "(" << i.first << "," << i.second << ")" << endl; } } void stl_unordered_multimap() { unordered_multimap p; for(auto i = 0;i < 20;i++) { p.insert({i,"hello"}); cout << "{"<< i << ",helllo} " << "em size:" << p.size() << ",bucket size:" << p.bucket_count() << endl; } print_unordered_multimap(p); cout << "p.bucket_size(p.bucket(1)):" << p.bucket_size(p.bucket(1)) << endl; } **unordered_set.cpp** #include #include using namespace std; template static void printf_unordered_set(T const& us) { for(auto i : us) cout << i << " "; cout << endl; } void stl_unordered_set() { unordered_set us; for(auto i = 0;i < 100;i++) { us.insert(i); } cout << "unordered_set:"; printf_unordered_set(us); cout << "bucket_count:" << us.bucket_count() << endl; cout << "max_bucket_count:" << us.max_bucket_count() << endl; cout << "us.load_factor():" << us.load_factor() << endl; cout << "us.max_load_factor():" << us.max_load_factor() << endl; cout << "new unordered_set(us.rehash(10) us.reserve(3)):"; us.rehash(10); us.reserve(3); printf_unordered_set(us); cout << "bucket_count:" << us.bucket_count() << endl; cout << "max_bucket_count:" << us.max_bucket_count() << endl; cout << "us.load_factor():" << us.load_factor() << endl; cout << "us.max_load_factor():" << us.max_load_factor() << endl; } **vector.cpp** #include #include using namespace std; template static void printf_sentence(T const &s) { for(auto i : s) cout << i ; cout << endl; cout << "sentence.capacity:" << s.capacity() << endl; cout << "sentence.size:" << s.size() << endl; cout << "sentence.max_size:" << s.max_size() << endl; } void stl_vector() { vector sentence; sentence.push_back('h'); sentence.push_back('e'); sentence.push_back('l'); sentence.push_back('l'); sentence.push_back('o'); sentence.push_back('\n'); cout << "sentence :"; printf_sentence(sentence); cout << "assign sentence :"; sentence.assign({'w','o','r','d','!'}); printf_sentence(sentence); cout << "insert sentence :"; sentence.insert(sentence.begin(),{'h','e','l','l','o',' '}); printf_sentence(sentence); cout << "emplace sentence :"; sentence.emplace(sentence.end(),'!'); printf_sentence(sentence); cout << "earse sentence :"; sentence.erase(sentence.end()-1); sentence.erase(sentence.begin(),sentence.begin()+6); printf_sentence(sentence); cout << "emplace_back sentence :"; sentence.emplace_back('?'); printf_sentence(sentence); cout << "pop_back sentence :"; sentence.pop_back(); printf_sentence(sentence); cout << "resize sentence :"; sentence.resize(10); printf_sentence(sentence); cout << "shrink_to_fit sentence :"; sentence.shrink_to_fit(); printf_sentence(sentence); cout << "clear sentence :"; sentence.clear(); printf_sentence(sentence); } **结果示例:** ![](https://i-blog.csdnimg.cn/direct/9de3dbbaa1df41d3872045d567cd61ae.png) ![](https://i-blog.csdnimg.cn/direct/d1757d11d66b4af68846133fb4b26975.png) ![](https://i-blog.csdnimg.cn/direct/303a49c4179849c28eba63bbdaadcc47.png) ![](https://i-blog.csdnimg.cn/direct/af79e320bf0c469ab95156147c1d2f38.png) ![](https://i-blog.csdnimg.cn/direct/bf7bae26c6b449478eb281075df3502e.png) ![](https://i-blog.csdnimg.cn/direct/b42da3bf5df542beab89e718bd559c43.png) **demo4:** **泛型算法** **目录:** ![](https://i-blog.csdnimg.cn/direct/e41709c8bc1f411798ad57edb673a320.png) **run.sh** #!/bin/bash if [ -f ./Makefile ] then make clean fi cmake . make echo "---------------------------------" ./pro **check_mem.sh** valgrind --tool=memcheck --leak-check=full --show-reachable=yes --trace-children=yes -s ./pro **clean.sh** #!/bin/bash rm -rf CMakeFiles pro Makefile CMakeCache.txt cmake_install.cmake **CMakeLists.txt** CMAKE_MINIMUM_REQUIRED(VERSION 2.20) #最低版本要求 SET(CMAKE_CXX_COMPILER "g++-11") #设置g++编译器 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g") #添加编译选项 PROJECT(CLASS) #设置工程名 MESSAGE(STATUS "string test") #打印消息 ADD_EXECUTABLE(pro main.cpp) #生成可执行文件 **main.cpp** #include #include #include #include using namespace std; template class gt { public: bool operator()(const T& f,const T& l) { return (f > l); } }; template static void print_vector(const T& v) { for(auto i : v) cout << i << " "; cout << endl; } auto even_num = [](const int& n)->bool{return (n % 2 == 0);}; auto grater_10 = [](const int& n){return (n > 10);}; int main() { vector a = {1,6,3,9,7}; vector b = {1,2,3,1,2,3,1,2,3}; vector c = {1,3,8}; vector d = {1,3,8}; vector e = {1,3,9}; vector f = {1,3,8}; vector g = {1,3,8}; vector h = {2,4,6}; vector j = {2,4,1,2,2,2,2,4}; vector k(6); cout << "for_earch(f++) bfore:"; print_vector(a); for_each(a.begin(),a.end(),[](int& f){f++;}); cout << "for_earch(f++) end:"; print_vector(a); if(!(all_of(a.begin(),a.end(),even_num))) cout << "all_of have no even_num" << endl; if(any_of(a.begin(),a.end(),even_num)) cout << "any_of have even_num" << endl; if(any_of(a.begin(),a.end(),grater_10)) cout << "none have num grater 10" << endl; if(find(a.begin(),a.end(),10) != a.end()) cout << "find 9" << endl; if(auto it = find_if(a.begin(),a.end(),even_num); it != a.end()) cout << "find if :the first em support even_num func :" << *it << endl; if(auto it = find_if_not(a.begin(),a.end(),even_num); it != a.end()) cout << "find if :the first em not support even_num func :" << *it << endl; for(auto t : {vector{-1,-2,-3},{4,5,6}}) { auto it = find_end(b.begin(),b.end(),t.begin(),t.end(),[](const int& bf,const int& tf) {return (abs(bf) == abs(tf));}); if(it == b.end()) { cout << "{4,5,6} have no found" << endl; } else { cout << "{1,2,3} last pos:" << distance(b.begin(),it) << endl; } } auto it = find_first_of(a.begin(),a.end(),c.begin(),c.end(),[](int& af,int& cf) {return ((af) == (++cf));}); if(it != a.end()) cout << "the first em of find_first_of func : " << *it << endl; auto cn = count_if(a.begin(),b.begin(),even_num); cout << "the even_num's num of a: " << cn << endl; pair< vector::iterator,vector::iterator > p; p = mismatch(d.begin(),d.end(),e.begin(),[](int& df,int& ef) {return ((++df) == (++ef));}); cout << "mismatch ,the firstly different em in two vector :" << *p.first << "," << *p.second << endl; if(equal(f.begin(),f.end(),g.begin(),[](int& ff,int& gf) {return ((++ff) == (++gf));})) cout << "g is same of f" << endl; auto tmp = search(b.begin(),b.end(),h.begin(),h.end(),[](int& bf,int& hf) {return ((bf) == (hf/2));}); cout << "{1,2,3} last pos:" << distance(b.begin(),tmp) << endl; auto sn = search_n(j.begin(),j.end(),2,2,[](const int& jf,const int& v) ->bool {return (jf == v);}); cout << "the first em pos:" << distance(j.begin(),sn) << endl; cout << "copy :"; copy_if(a.begin(),a.end(),ostream_iterator(cout," "),[](int& n){return(n %2 == 0);}); cout << endl; cout << "copy_n :"; copy_n(a.begin(),2,ostream_iterator(cout," ")); cout << endl; cout << "copy_backward :"; copy_backward(a.begin(),a.end(),k.end()); print_vector(k); cout << "move:"; move(a.begin(),a.end(),ostream_iterator(cout," ")); cout << endl; cout << "move_backward:"; move_backward(a.begin(),a.end(),k.end()); print_vector(k); cout << "swap before b:"; print_vector(b); cout << "swap before c:"; print_vector(c); swap_ranges(c.begin(),c.end(),b.begin()); cout << "swap after b:"; print_vector(b); cout << "swap after c:"; print_vector(c); cout << "transform:"; transform(c.begin(),c.end(),c.begin(),c.begin(),[](const int& c1,const int c2){return (c1 + c2);}); print_vector(c); cout << "replace_if:"; replace_if(a.begin(),a.end(),even_num,2); print_vector(a); cout << "replace_copy_if:"; replace_copy_if(a.begin(),a.end(),ostream_iterator(cout," "),even_num,1); cout << endl; cout << "fill:"; fill(a.begin(),a.end(),6); print_vector(a); cout << "fill_n:"; fill_n(a.begin(),3,2); print_vector(a); cout << "generate:"; generate(a.begin(),a.end(),[n = 0]() mutable {return n++;}); print_vector(a); cout << "generate_n:"; generate_n(ostream_iterator(cout," "),3,[n = 0]() mutable {return n++;}); cout << endl; cout << "remove:"; a.erase(remove_if(a.begin(),a.end(),even_num),a.end()); print_vector(a); cout << "remove_copy_if:"; remove_copy_if(b.begin(),b.end(),ostream_iterator(cout," "),even_num); cout << endl; cout << "uniqe before:"; print_vector(j); unique(j.begin(),j.end()); cout << "uniqe after:"; print_vector(j); cout << "reverse:"; reverse(j.begin(),j.end()); print_vector(j); cout << "reverse_copy:"; reverse_copy(j.begin(),j.end(),ostream_iterator(cout," ")); cout << endl; cout << "rotate:"; rotate(j.begin(),j.begin()+1,j.end()); print_vector(j); cout << "rotate_copy:"; rotate_copy(j.begin(),j.begin()+3,j.end(),ostream_iterator(cout," ")); cout << endl; cout << "sort:"; sort(j.begin(),j.end()); print_vector(j); cout << "sort:"; sort(j.begin(),j.end(),gt()); print_vector(j); cout << "stable_sort"; struct people { int num; string name; }; vector pe{{2,"xiaoming"},{1,"xiaohua"},{2,"xiaoli"}}; stable_sort(pe.begin(),pe.end(),[](const people& f,const people& l){return (f.num > l.num);}); for(auto i : pe) cout << "{" << i.num << "," << i.name << "} "; cout << endl; cout << "upper_bound:"; auto ub = upper_bound(c.begin(),c.end(),3); cout << *ub << endl; cout << "b:"; sort(b.begin(),b.end()); print_vector(b); cout << "c:"; print_vector(c); cout << "merge:"; merge(b.begin(),b.end(),c.begin(),c.end(),ostream_iterator(cout," ")); cout << endl; return 0; } **执行结果:** ![](https://i-blog.csdnimg.cn/direct/2efb4630255349bca52227f2e7eb6b3d.png) ![](https://i-blog.csdnimg.cn/direct/64aa9f65de3e40c1bcbe0b31eb77a687.png) ![](https://i-blog.csdnimg.cn/direct/9b0e0caa558c4aeebbab36e6e9c956da.png) **demo5:** **特化萃取** **目录:** ![](https://i-blog.csdnimg.cn/direct/e1de60785bed4641810ab4c327cae6b6.png) **run.sh** #!/bin/bash if [ -f ./Makefile ] then make clean fi cmake . make echo "---------------------------------" ./pro **clean.sh** #!/bin/bash rm -rf CMakeFiles pro Makefile CMakeCache.txt cmake_install.cmake **check_mem.sh** valgrind --tool=memcheck --leak-check=full --show-reachable=yes --trace-children=yes -s ./pro **CMakeLists.txt** CMAKE_MINIMUM_REQUIRED(VERSION 2.20) #最低版本要求 SET(CMAKE_CXX_COMPILER "g++-11") #设置g++编译器 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g") #添加编译选项 PROJECT(CLASS) #设置工程名 MESSAGE(STATUS "template test") #打印消息 ADD_EXECUTABLE(pro main.cpp) #生成可执行文件 **main.cpp** #include #include using namespace std; //函数模版 template void comp(const T& f,const T& l) { if(f > l) { cout << f << " > " << l << endl; } else { cout << f << " < " << l << endl; } } //函数模版特化 template<> void comp(const string& f,const string& l) { if(f.size() > l.size()) { cout << "string :" << f << " > " << l << endl; } else { cout << "string :" << f << " < " << l << endl; } } void comp(const char *f,const char *l) { if(strlen(f) > strlen(l)) { cout << "char* :" << strlen(f) << " > " << strlen(l) << endl; } else { cout << "char* :" << strlen(f) << " < " << strlen(l) << endl; } } //类模版 template class Argv { public: Argv(){}; Argv(T1 argv1,T2 argv) { this->argv1 = argv1; this->argv = argv; } void print_info() { cout << " argv1 : " << argv1 << "," << "argv :" << argv << endl; } private: T1 argv1; T2 argv; }; //类模版偏特化 template class Argv { public: Argv(){}; Argv(T argv1,int argv) { this->argv1 = argv1; this->argv = argv; } void print_info() { cout << " argv1 : " << argv1 << "," << "argv :" << argv << endl; } private: T argv1; int argv; }; template class Argv { public: Argv(){}; Argv(T argv1,int argv) { this->argv1 = argv1; this->argv = argv; } void print_info() { cout << " argv1 : " << argv1 << "," << "argv :" << argv << endl; } private: T argv1; int argv; }; template class Argv { public: Argv(){}; Argv(T argv1,int argv) { this->argv1 = argv1; this->argv = argv; } void print_info() { cout << " argv1 : " << argv1 << "," << "argv :" << argv << endl; } private: T argv1; int argv; }; //类模版全特化 template<> class Argv { public: Argv(){}; Argv(string argv1,int argv) { this->argv1 = argv1; this->argv = argv; } void print_info() { cout << " argv1 : " << argv1 << "," << "argv :" << argv << endl; } private: string argv1; int argv; }; template void copy_t(T* dest,const T* src,const int cnt) { if(is_pod::value) { cout << "is_pod "; memcpy(dest,src,cnt*sizeof(T)); } else { cout << "is not pod "; for(auto i = 0;i < cnt;i++) { dest[i] = src[i]; } } } void copy_t(string &dest,string &src) { dest = src; } //萃取实现is_pod template class is_pod_t { public: static bool value; }; template bool is_pod_t::value = false; template<> class is_pod_t { public: static bool value; }; bool is_pod_t::value = true; template<> class is_pod_t { public: static bool value; }; bool is_pod_t::value = true; template<> class is_pod_t { public: static bool value; }; bool is_pod_t::value = true; template<> class is_pod_t { public: static bool value; }; bool is_pod_t::value = true; template<> class is_pod_t { public: static bool value; }; bool is_pod_t::value = true; template void copy_t1(T* dest,const T* src,const int cnt) { if(is_pod_t::value) { cout << "is_pod "; memcpy(dest,src,cnt*sizeof(T)); } else { cout << "is not pod "; for(auto i = 0;i < cnt;i++) { dest[i] = src[i]; } } } //萃取实现is_pod struct Type { typedef int value_type; }; struct True_type { bool get_type() { return true; } }; struct False_type { bool get_type() { return false; } }; template struct is_pod_s { typedef False_type value_type; }; template<> struct is_pod_s { typedef True_type value_type; }; template<> struct is_pod_s { typedef True_type value_type; }; template<> struct is_pod_s { typedef True_type value_type; }; template<> struct is_pod_s { typedef True_type value_type; }; template<> struct is_pod_s { typedef True_type value_type; }; template void copy_t2(T* dest,const T* src,const int cnt) { if(is_pod_s::value) { cout << "is_pod "; memcpy(dest,src,cnt*sizeof(T)); } else { cout << "is not pod "; for(auto i = 0;i < cnt;i++) { dest[i] = src[i]; } } } int main() { string s1 = "linux"; string s2 = "windows"; string s3[3] = {"linux","windows","macos"}; string s4[3]; string s6[3]; string s7[3]; string s5; int a = 6; int b; int c; comp(4.8,5.6); comp(s1,s2); comp("linux","windows"); Argv a1(s1,27); Argv a2(s1,s2); Argv a3(27,s2); Argv a4(a,27); Argv a5(s1,27); Argv a6(a,27); a1.print_info(); a2.print_info(); a3.print_info(); a4.print_info(); a5.print_info(); a6.print_info(); copy_t(s4,s3,3); cout << "s4 :"; for(auto i = 0;i < 3;i++) { cout << s4[i] << " "; } cout << endl; copy_t(s5,s1); cout << "s1:" << s1 << " s5: " << s5 << endl; copy_t1(s6,s3,3); cout << "s6 :"; for(auto i = 0;i < 3;i++) { cout << s6[i] << " "; } cout << endl; copy_t1(&b,&a,1); cout << "a:" << a << " b: " << b << endl; copy_t1(s7,s3,3); cout << "s6 :"; for(auto i = 0;i < 3;i++) { cout << s7[i] << " "; } cout << endl; copy_t1(&c,&a,1); cout << "a:" << a << " c: " << c << endl; return 0; } **执行结果:** ![](https://i-blog.csdnimg.cn/direct/851b1d6e35304958a076bf9fdc862bb5.png) **demo6:** **智能指针** **目录:** ![](https://i-blog.csdnimg.cn/direct/5386ffb6b81f450fad68fbbbaae40af0.png) **run.sh** #!/bin/bash if [ -f ./Makefile ] then make clean fi cmake . make echo "---------------------------------" ./pro **clean.sh** #!/bin/bash rm -rf CMakeFiles pro Makefile CMakeCache.txt cmake_install.cmake **check_mem.sh** valgrind --tool=memcheck --leak-check=full --show-reachable=yes --trace-children=yes -s ./pro **CMakeLists.txt** CMAKE_MINIMUM_REQUIRED(VERSION 2.20) #最低版本要求 SET(CMAKE_CXX_COMPILER "g++-11") #设置g++编译器 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g") #添加编译选项 PROJECT(CLASS) #设置工程名 MESSAGE(STATUS "string test") #打印消息 ADD_EXECUTABLE(pro main.cpp) #生成可执行文件 **main.cpp** #include #include #include using namespace std; template class Test { private: public: T *num; Test(){}; Test(int size) { cout << "user con" << endl; num = new T[SIZE]; if(num != NULL) { for(auto i = 0;i < SIZE;i++) num[i] = size; } }; ~Test() { cout << "user descon" << endl; if(num != NULL) delete[] num; }; void print() { for(auto i = 0;i < SIZE;i++) cout << num[i] << " " ; cout << endl; } }; template void set_t(T *t) { for(auto i = 0;i < SIZE;i++) t[i] = i; } template void get_t(T *t) { for(auto i = 0;i < SIZE;i++) cout << t[i] << " "; cout << endl; } class front; class back; class front { public: //shared_ptr bptr; weak_ptr bptr; front(){}; front(int num) { cout << "front" << endl; }; ~front() { cout << "~front()" << endl; } }; class back { public: //shared_ptr fptr; weak_ptr fptr; back(){}; back(int num) { cout << "back" << endl; }; ~back() { cout << "~bak()" << endl; } }; int main() { unique_ptr> up1(new Test(3)); cout << "up1 :"; up1->print(); //移动构造时会将前对象的所有权转移给当前对象 unique_ptr> up2(move(up1)); cout << "up2 :"; up2->print(); unique_ptr> up3 = unique_ptr>(new Test(3)); cout << "up3 :"; up3->print(); using deleter = void(*)(int*); //定义删除器类型别名 unique_ptr up4(new int[3],[](int *p){delete [] p;}); set_t(up4.get()); cout << "up4 :"; get_t(up4.get()); //重新绑定对象前会调用前对象的删除器删除前对象 up4.reset(new int[4]); set_t(up4.get()); cout << "up4 :"; get_t(up4.get()); unique_ptr up5(new int[5],[](int *p){delete [] p;}); set_t(up5.get()); cout << "up5 :" ; get_t(up5.get()); up4.swap(up5); cout << "up4 :"; get_t(up4.get()); cout << "up5 :" ; get_t(up5.get()); //释放权限后要手动释放内存 int *p6 = up4.release(); delete p6; int *p7 = up5.release(); delete p7; //拷贝构造会增加管理对象,移动构造不会 shared_ptr> sp1(new Test(3)); cout << "sp1 :"; sp1->print(); shared_ptr> sp2(sp1); cout << "sp2 :"; sp2->print(); shared_ptr> sp3 = sp1; cout << "sp3 :"; sp3->print(); shared_ptr> sp4(move(sp1)); cout << "sp4 :"; sp4->print(); cout << "sp1 use_count :" << sp1.use_count() << endl; cout << "sp2 use_count :" << sp2.use_count() << endl; cout << "sp3 use_count :" << sp3.use_count() << endl; cout << "sp4 use_count :" << sp4.use_count() << endl; weak_ptr> wp; { auto sp5 = make_shared>(6); cout << "sp5 :"; sp5->print(); if(sp5.unique()) cout << "sp5 use_count = 1" << endl; if(!wp.lock()) wp = sp5; if(wp.expired()) cout << "sp5 deleted 1" << endl; wp.reset(); cout << "wp.use_count :" << wp.use_count() << endl; if(wp.expired()) cout << "sp5 deleted 2" << endl; } if(wp.expired()) cout << "sp5 deleted 3" << endl; shared_ptr f(new front(1)); shared_ptr b(new back(1)); cout << "f.use_count :" << f.use_count() << endl; cout << "b.use_count :" << b.use_count() << endl; f->bptr = b; b->fptr = f; cout << "f.use_count :" << f.use_count() << endl; cout << "b.use_count :" << b.use_count() << endl; return 0; } **结果示例:** ![](https://i-blog.csdnimg.cn/direct/1ff04fb785e84b3681a822dfd005fd13.png) ![](https://i-blog.csdnimg.cn/direct/70ac3e989f904e7d876f2ab796df62bb.png)

相关推荐
钢铁男儿2 分钟前
C# 方法(栈帧)
开发语言·c#
忆源2 小时前
【Qt】之音视频编程1:QtAV的背景和安装篇
开发语言·qt·音视频
敲键盘的小夜猫2 小时前
Python核心数据类型全解析:字符串、列表、元组、字典与集合
开发语言·python
李匠20242 小时前
C++GO语言微服务之图片、短信验证码生成及存储
开发语言·c++·微服务·golang
czy87874755 小时前
C语言主要标准版本的演进与核心区别的对比分析
c语言
巨龙之路5 小时前
C语言中的assert
c语言·开发语言
2301_776681656 小时前
【用「概率思维」重新理解生活】
开发语言·人工智能·自然语言处理
熊大如如6 小时前
Java 反射
java·开发语言
ll7788117 小时前
C++学习之路,从0到精通的征途:继承
开发语言·数据结构·c++·学习·算法
我不想当小卡拉米7 小时前
【Linux】操作系统入门:冯诺依曼体系结构
linux·开发语言·网络·c++