标准模板库 STL(Standard Template Library),是 C++ 标准库的一部分,不需要单独安装,只需要#include 头文件
。STL提供了容器,迭代器,函数对象等类模板和算法(函数模板)。
容器:类似于数组,可以存放一组同类型的对象;
常用的容器为模板类vector(包含在头文件vector中),vector类似于数组,但具有更多功能:
vector示例:作为数组
vector示例:其他操作
STL的每个容器都有一个迭代器,被定义为容器的公有嵌套类,迭代器都分为两种迭代器:iterator
和const_iterator
。迭代器的功能类似指针,用于遍历容器中的元素。
对于const_iterator
,只能用于读取容器内的元素,不能改变其值
容器中一般提供了两个成员函数:begin和end,分别返回指向第一个节点和超尾节点的迭代器。(超尾节点是容器最后一个元素后面的节点,内容为NULL,即容器的超尾节点迭代器指向NULL)
vector中迭代器的使用
为什么使用迭代器?
for(iterator=begin(); iterator!=end(); iterator++)
一样的遍历,STL在每个容器类中都写了iterator这样的嵌套类,为容器的访问和修改提供了便利。for item in iterable
什么是函数对象
将一个函数作为另一个函数的参数
函数对象的应用举例
先设计一个在某容器中遍历的函数:
再设计一个在某容器中,将迭代器所指向的数据加1的函数
现在思考,能不能把这两个函数变得统一:回顾37.函数指针,将函数作为统一函数的参数;
我们先将需要的操作设计为函数output和add,此时的设计只需要考虑容器内的单个元素,所以实现更简单:
我们再设计统一函数general:
void general (vector<int>::iterator begin, vector<int>::iterator end, 指向函数的指针)
但是对于指向函数的指针这个参数,在统一函数的声明中,我们需要为指向函数的指针声明返回类型,形式参数列表。换言之,我们要用指向函数的指针实现统一,我们至少要确保output和add的函数原型是一样的(除了函数名不同)。
那我们该怎么做?
函数对象(参数)
,可以看作是函数对象在使用函数调用符()
,所以:函数对象(参数)
等价于 函数对象()参数
STL中,为了便于对任意容器进行逐一处理(general只能对vector操作),已经实现了for_each函数作为统一函数(包含在库algorithm中),for_each函数对某个迭代器范围内的每个元素执行指定操作,for_each被声明为:
template<class InputIterator, class Function>
Function for_each (InputIterator first, InputIterator last, Function f);
注意输入for_each的函数对象(Function f)应当每次用于容器的一个元素;
因此,上面过程可以用for_each实现为:
STL预定义函数对象:C++将许多常见操作定义为函数对象(函数符),方便作为for_each和general这样的统一函数的参数(使用预定义的函数符必须包含头文件functional),预定义函数对象本质上是类模板
示例
在STL中,算法是处理容器的非成员函数,比如:排序sort,拷贝copy,查找find;包含在头文件algorithm中,算法的参数通常包含一个迭代器范围。
示例:排序一个vector
示例:vector中的查找