标准模板库:
简单地说,标准模板库( STL )是一组模板类和函数,向程序员提供了:• 用于存储信息的容器;• 用于访问容器存储的信息的迭代器;• 用于操作容器内容的算法。
关于STL可见:
(4条消息) 【C/C++】STL详解_沉晓的博客-CSDN博客_c++的stl
STL 容器
容器是用于存储数据的
STL
类,
STL
提供了两种类型的容器类:
• 顺序容器;• 关联容器。
另外,
STL
还提供了被称为容器适配器(
Container Adapter
)的类,它们是顺序容器和关联容器的变种,包含的功能有限,用于满足特殊的需求。
顺序容器
顾名思义,顺序容器按顺序存储数据,如数组和列表。顺序容器具有插入速度快但查找操作相对
较慢的特征。
STL
顺序容器如下所示。
• std::vector :操作与动态数组一样,在最后插入数据;可将 vector 视为书架,您可在一端添加和拿走图书。• std::deque :与 std::vector 类似,但允许在开头插入或删除元素。• std::list :操作与双向链表一样。可将它视为链条,对象被连接在一起,您可在任何位置添加或删除对象。• std::forward_list :类似于 std::list ,但是单向链表,只能沿一个方向遍历。
容器适配器
容器适配器(
Container Adapter
)是顺序容器和关联容器的变种,其功能有限,用于满足特定的需
求。主要的适配器类如下所示。
• std::stack :以 LIFO (后进先出)的方式存储元素,让您能够在栈顶插入(压入)和删除(弹出)元素。• std::queue :以 FIFO (先进先出)的方式存储元素,让您能够删除最先插入的元素。• std::priority_queue :以特定顺序存储元素,因为优先级最高的元素总是位于队列开头。
STL 迭代器
最简单的迭代器是指针。给定一个指向数组中的第一个元素的指针,可递增该指针使其指向下一
个元素,还可直接对当前位置的元素进行操作。
STL
中的迭代器是模板类,从某种程度上说,它们是泛型指针。这些模板类让程序员能够对
STL
容器进行操作。注意,操作也可以是以模板函数的方式提供的
STL
算法,迭代器是一座桥梁,让这些模板函数能够以一致而无缝的方式处理容器,而容器是模板类。
STL
提供的迭代器分两大类。
• 输入迭代器:通过对输入迭代器解除引用,它将引用对象,而对象可能位于集合中。最严格的输入迭代器确保只能以只读的方式访问对象。• 输出迭代器:输出迭代器让程序员对集合执行写入操作。最严格的输出迭代器确保只能执行写入操作。
上述两种基本迭代器可进一步分为三类。
• 前向迭代器:这是输入迭代器和输出迭代器的一种细化,它允许输入与输出。前向迭代器可以是 const 的,只能读取它指向的对象;也可以改变对象,即可读写对象。前向迭代器通常用于单向链表。• 双向迭代器:这是前向迭代器的一种细化,可对其执行递减操作,从而向后移动。双向迭代器通常用于双向链表。• 随机访问迭代器:这是对双向迭代器的一种细化,可将其加减一个偏移量,还可将两个迭代器相减以得到集合中两个元素的相对距离。随机访问迭代器通常用于数组。
注:从实现层面说,可将“细化”视为继承或具体化。
STL 算法
查找、排序和反转等都是标准的编程需求,不应让程序员重复实现这样的功能。因此
STL
以
STL
算法的方式提供这些函数,通过结合使用这些函数和迭代器,程序员可对容器执行一些最常见的操作。
最常用的
STL
算法如下所示。
• std::find :在集合中查找值。• std::find_if :根据用户指定的谓词在集合中查找值。• std::reverse :反转集合中元素的排列顺序。• std::remove_if :根据用户定义的谓词将元素从集合中删除。• std::transform :使用用户定义的变换函数对容器中的元素进行变换。
这些算法都是
std
命名空间中的模板函数,要使用它们,必须包含标准头文件
<algorithm>
。
#include<algorithm>
使用迭代器在容器和算法之间交互
使用关键字 auto 让编译器确定类型
在程序清单
15.1
中,有多个迭代器声明,这些声明类似于下面这样:
vector <int>::iterator arrIterator = intArray.begin ();
上述迭代器类型定义看起来令人恐怖。如果您使用的是遵循
C++11
的编译器,可将这行代码简化
成下面这样:
auto arrIterator = intArray.begin (); // compiler detects type
注意到将变量类型声明为
auto
时,必须对其进行初始化,这样编译器才能根据初始值推断变量的
类型。
STL 字符串类
STL
提供了一个专门为操纵字符串而设计的模板类:
std::basic_string<T>
,该模板类的两个常用具
体化如下所示。
• std::string :基于 char 的 std::basic_string 具体化,用于操纵简单字符串。• std::wstring :基于 wchar_t 的 std::basic_string 具体化,用于操纵宽字符串,通常用于存储支持各种语言中符号的 Unicode 字符。
问与答
问:我需要一个数组,但不知道它应包含多少个元素。请问我应使用哪种 STL 容器?
答:
std::vector
或
std::deque
能够很好地满足这种需求。这两种容器都负责管理内存,并可根据应
用程序需求动态地调整大小。
问:我的应用程序经常需要执行搜索操作,我应选择哪种容器?
答:
诸如
std::map
和
std::set
及其
unordered
变种等关联容器最适合于需要经常进行搜索的应用程序。
问:我要存储键-值对,并希望能够快速完成查找,但键可能不是唯一的。我应选择哪种容器?
答:
关联容器
std::multimap
适合这种需求。
multimap
可存储非唯一的键
-
值对,查找速度也快,这是关联容器的一个特点。
问:我要开发一个能够在不同平台和编译器之间移植的应用程序,该程序还需要使用能够根据键
快速查询的容器。我应使用 std::map 还是 std::hash_map?
答:
移植性是一个重要约束条件,必须使用遵循标准的容器。
hash_map
不是
C++
标准的一部分,
因此并非所有的平台都支持它。如果您使用的是遵循
C++11
的编译器,也可使用
std::unordered_map
。
参考来源:
《21天学通C++》