本文简单介绍STL(Standard Template Library)的相关知识。

1 概述

STL(Standard Template Library),即标准模板库,是惠普实验室开发的一系列软件的统称。从根本上说,STL是一些“容器”的集合,这些“容器”有list、vector、set、map等。同时,STL也是算法和其他一些组件的集合。STL现在是C++编程语言的一部分,因此不用安装额外的库文件。

2 WHY STL

开发STL的目的是标准化组件,这样就可以使用现成的组件,而不必在使用时重新开发了。

STL是一个标准,只规定了STL的接口,内部实现没有要求。当前STL存在许多实现版本,如“PJ STL”(被Visual C++采用)、“RW STL”、“SGI STL”等。由于“SGI STL”版本注释丰富、结构清晰、可读性最强,同时也被GCC采用,所以是现在最流行的STL版本。

2 STL组件

STL包括容器(containers)、迭代器(iterators)、空间配置器(allocator)、配接器/适配器(adapters)、算法(algorithms)、仿函数(functors)六个组件。

现在分别对这些组件进行介绍。

2.1 容器(containers)

在实际的软件开发过程中,数据结构本身的重要性不逊于(操作于数据结构的)算法,特别是当程序中存在着对时间要求很高的部分时,数据结构的选择就显得更加重要。

虽然经典的数据结构数量有限,但是我们在日常开发中,常常重复着一些为了实现向量、链表等结构而编写的代码,这些代码大都十分相似,只是为了适应不同数据的变化而在细节上有所出入,这样就带来了重复开发的问题。

STL容器的出现就是为了解决上面的问题。STL容器允许我们重复利用已有的数据结构,构造自己在特定类型下的数据结构。通过设置一些模板类,STL容器对最常用的数据结构提供了支持,这些模板的参数允许我们指定容器中元素的数据类型,从而将我们许多重复而乏味的工作简化。

STL容器作为常用数据结构,大致分为两类:

  1. 序列容器,即通过序列化访问的容器,如vector,list,deque;
  2. 关联容器,即通过键值对访问的容器,如set,map。

STL容器在实现上属于类模板(class template)。

STL容器主要由头文件<vector>,<list>,<deque>,<set>,<map>,<stack>和<queue>组成。

2.2 迭代器(iterators)

在STL中,迭代器用来将算法和容器联系起来。几乎STL提供的所有算法都是通过迭代器存取容器中的元素序列进行工作的。

迭代器可以理解为“一套访问容器的接口”,其行为类似于指针,它为不同算法提供了相对统一的对容器中元素的访问方式,使得设计算法时无需过多地关注数据。

每一个容器都定义了其本身所专有的迭代器,用以存取容器中的元素。

2.3 空间配置器(allocator)

为容器提供空间配置和释放、对象构造和析构的服务。

通常我们可以在代码中用“#include <memory>”来包含它。

STL空间配置器在实现上属于类模板(class template)。

2.4 配接器(adapters)

配接器(adapter):将一种容器修饰为功能不同的另一种容器,如以容器vector为基础,在其上实现stack,stack的行为也是一种容器,这就是一种配接器。除此之外,还有迭代器配接器和仿函数配接器。

2.5 算法(algorithms)

C++通过模板的机制允许推迟对某些类型的选择,直到真正想使用模板或者说对模板进行特化的时候(才对某些类型进行选择)。STL就利用了这C++的这一特点,提供了相当多的有用算法。

STL提供了大约100个实现算法的模版函数,比如算法“for_each”是指定序列中的每一个元素调用指定的函数;算法“stable_sort”以你所指定的规则对序列进行稳定性排序等等。这样一来,只要我们熟悉了STL之后,许多代码就可以被大大的简化,只需要通过调用一两个算法模板,就可以完成所需要的功能,大大地提升了编码效率。

STL提供了一套常用的算法,其中的常用功能涉及到:比较、交换、查找、遍历操作、复制、修改、移除、反转、排序、合并等等。

STL的算法在实现上,可以认为是一种函数模板(function template)。

2.6 仿函数(functors)

STL的仿函数,作为函数使用的对象,用于泛化算法中的操作。