STL(starand template lib):标准模板库
背景:
1、c++面向对象和泛型编程思想,目的是复用性的提升
2、为了建立数据结构和算法的一套标准诞生了STL
STL六大组件
分别是容器、算法、迭代器、仿函数、适配器(配接器)、空间配置器
容器:
容器可分为序列式容器和关联式容器
函数对象(仿函数):
概念
本质:
函数对象(仿函数)本质上是一个类,不是一个函数
函数对象使用:
下面列子:
1、 //函数对象在使用时,可以像普通函数那样调用,可以有参数,也可以有返回值
class MyAdd {
public:
int operator()(int v1, int v2)
{
return v1 + v2;
}
};
void test02()
{
MyAdd myAdd;
cout << myAdd(10, 10) << endl; //这里对象使用就像函数调用
}
2、函数对象超出普通函数的概念,函数对象可以有自己的状态
class MyAdd {
public:
int operator()(int v1, int v2)
{
return v1 + v2;
count++;
}
int count; 记录operator()函数调用的次数 也就是有自己的状态
};
3、函数对象可以作为参数传递
void doPrint(MyAdd &myAdd, int v1, int v2)
{
myAdd(v1, v2);
}
谓词:
概念:
其中一元谓词的例子如下:
class PrintWorker {
public:
bool operator()(int val) //一元谓词的返回必须时bool
{
return val > 5;
}
};
void test03()
{
vector<int> v;
for (int i = 0; i < 5; i++)
{
v.push_back(i);
}
vector<int>::iterator pos = find_if(v.begin(), v.end(), PrintWorker()); //返回满足条件的迭代器 PrintWorker()对象函数返回true时
if (pos != v.end())
{
cout << "找到了大于5的数" << endl;
cout << *pos << endl;
}
else {
cout << "m没找到大于5的数" << endl;
}
}
二元谓词例子如下:
//二元谓词
class MyCompare {
public:
bool operator()(int val1, int val2)
{
return val1 > val2;
}
};
void test04()
{
vector<int> v;
v.push_back(10);
v.push_back(40);
v.push_back(30);
v.push_back(20);
v.push_back(60);
v.push_back(50);
//系统默认提供的sort 算法策略是默认从小到大
sort(v.begin(), v.end());
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << *it << endl;
}
//使用函数对象(二元谓词)改变算法策略,改变规则为从大到小
sort(v.begin(), v.end(), MyCompare());
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << *it << endl;
}
}
下面讲述内建函数对象
内建函数对象:STL定义了一些函数对象
分类:
使用内建函数对象需要引入头文件 #include
算术仿函数:(+、-、*、/、!)
#include
void test05()
{
//negate 一元仿函数 取反
negate<int> n;
cout << n(20) << endl; //结果-20
// plus 二元仿函数 加法
plus<int> p;
cout << p(10, 20) << endl;
}
关系仿函数: (大于、小于)
这里是在学习shared_ptr智能指针时在操作STL iterator迭代器出现的错误
#include
#include
#include
using namespace std;
void listTest()
{
//list里依次插入shared_ptr管理的string对象
list<shared_ptr<string>> pstrList;
pstrList.emplace_back(make_shared<string>("111111"));
pstrList.emplace_back(make_shared<string>("222222"));
pstrList.emplace_back(make_shared<string>("333333"));
pstrList.emplace_back(make_shared<string>("444444"));
for (auto p : pstrList)
{
cout << *p << endl;
}
//这里需要完成删除erase指定对象
std::cout << "itertor erase test!!!" << std::endl;
for (list<shared_ptr<string>>::iterator itr = pstrList.begin(); itr != pstrList.end(); ++itr)
{
if (**itr == "333333")
{
cout << **itr << endl;
itr = pstrList.erase(itr); //这里需要注意erase后返回的itertor迭代器就指向了下一个元素
--itr; //所以这里需要-- ,不--的话就要出现cannot increment end list iterator错误
}
}
//打印erase之后的list
std::cout << "after erase!!!" << std::endl;
for (auto p : pstrList)
{
cout << *p << endl;
}
}
int main()
{
listTest();
}