本文主要探讨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:**
**模版**
**目录:**

**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;
}
**结果示例:**

**demo2:**
**string**
**目录:**

**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;
}
**结果示例:**

**demo3:**
**容器**
**目录:**

**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