STL 容器、迭代器和谓词研究






2.91/5 (18投票s)
2006 年 12 月 4 日
5分钟阅读

34669

518
通过讨论 std::vector 来研究 STL 容器、迭代器和谓词
引言
本文旨在借助 std::vector 介绍 C++ 标准模板库 (STL) 的容器和迭代器。在介绍容器时,本文涵盖了 std::vector 的一些函数用法;在介绍迭代器时,本文涵盖了谓词和函数指针。
容器
容器是容纳其他对象的对象。容器有两种类型:
1. 序列容器:它按顺序存储并允许数据检索。例如,vector 类定义了一个动态数组,deque 创建了一个双端队列,list 提供了一个线性列表。
2. 关联容器:它允许基于键高效地检索值。例如,map 提供对具有唯一键的值的访问。因此,map 存储键/值对,并允许在给定其键的情况下检索值。
容器使用分配器和谓词。
分配器管理内存。每个容器都有为其定义的分配器。分配器管理容器的内存分配。默认分配器是 allocator 类的一个对象,但如果专业应用程序需要,您可以定义自己的分配器。对于大多数用途,默认分配器就足够了。
有些容器使用一种特殊类型的函数,称为谓词。谓词有两种变体:一元和二元。一元谓词接受一个参数,而二元谓词接受两个参数。这些函数返回 true/false 结果。但使其返回 true 或 false 的精确条件由您定义。
容器 |
描述 |
所需头文件 |
Bitset |
一组位。 |
<bitset> |
Deque |
一个双端队列。 |
<deque> |
列表 |
一个线性列表。 |
<list> |
映射 |
存储键/值对,其中每个键仅与一个值相关联。 |
<map> |
Multimap |
存储键/值对,其中一个键可能与两个或更多值相关联。 |
<map> |
Multiset |
一个集合,其中每个元素不一定是唯一的。 |
<set> |
priority_queue |
一个优先队列。 |
<queue> |
队列 |
一个普通队列。 |
<queue> |
Set |
一个集合,其中每个元素都是唯一的。 |
<set> |
堆栈 |
一个栈。 |
<stack> |
向量 |
一个动态数组。 |
<vector> |
迭代器
迭代器提供遍历容器中存储元素的能力。它们或多或少是指针。迭代器有五种类型:
1. 随机访问:存储和检索值。元素可以随机访问。
2. 双向:存储和检索值。向前和向后移动。
3. 前向:存储和检索值。只向前移动。
4. 输入:只检索,不存储值。只向前移动。
5. 输出:只存储,不检索值。只向前移动。
除此之外,STL 还支持反向迭代器。它们是双向的或随机访问的。它们向后移动。例如,如果它指向最后一个元素,那么递增指针将指向倒数第二个元素。
让我们以 vector 模板类为例来理解容器、迭代器和谓词
Vector 概述
Vector 是一个容器类,它实现了动态数组,并根据需要增长。vector 的模板规范如下所示:
template <class T, class Aallocator = Allocator <T>>class vector
为了使用 vector,您需要包含 <vector> 头文件。vector 是 std 命名空间的一部分,因此您需要限定名称。这可以通过以下方式实现:
using std::vector;
vector<int> vInts;
或者您可以像这样完全限定名称:std::vector<int> vInts;
Vector 成员函数
函数 |
描述 |
赋值 |
擦除向量并将指定元素复制到空向量中。 |
at |
返回对向量中指定位置元素的引用 |
back |
返回对向量最后一个元素的引用 |
begin |
返回指向容器中第一个元素的随机访问迭代器。 |
capacity |
返回向量在不分配更多存储空间的情况下可以包含的元素数量。 |
clear |
擦除向量的元素 |
empty |
测试向量容器是否为空。 |
end |
返回指向向量末尾之外的随机访问迭代器 |
erase |
从指定位置删除向量中的一个或一系列元素。 |
front |
返回对向量中第一个元素的引用 |
get_allocator |
返回向量使用的分配器类的对象 |
插入 |
在向量中指定位置插入一个或多个元素。 |
max_size |
返回向量的最大长度 |
pop_back |
删除向量末尾的元素 |
push_back |
将元素添加到向量的末尾 |
rbegin |
返回反向向量中第一个元素的迭代器 |
rend |
返回反向向量末尾的迭代器 |
resize |
指定向量的新大小 |
reserve |
为向量对象保留最小存储长度。 |
size |
返回向量中元素的数量 |
swap |
交换两个向量的元素。 |
向量 |
构造特定大小的向量,或具有特定值的元素,或使用特定分配器,或作为其他向量的副本 |
Vector 运算符
运算符 |
描述 |
operator [] |
返回对指定位置的 |
创建 Vector
vector 容器有几个构造函数。以下是最常用的构造函数:
空的 int 向量
vector<int> vInt;
容纳 10 个 int 的向量
vector<int> vInt(10);
容纳 10 个 int 并初始化为 0 的向量
vector<int> vInt(10, int(0));
从另一个 int 向量构造的向量
vector<int> vIntA(vIntB);
填充 Vector
std::vector<CItem> m_vItem; m_vItem.push_back(Item);
上述代码构造了 m_vItem 向量,该向量将容纳 CItem 类型的对象。push_back 会在向量的末尾添加元素。
访问 Vector 元素
std::vector<CItem>::iterator m_iItem; for (m_iItem = m_vItem.begin();m_iItem != m_vItem.end(); m_iItem++) { index = m_List.InsertItem(0,m_iItem->GetNumber()); m_List.SetItemText(index,1,m_iItem->GetName()); }
上述代码构造了 m_iItem 迭代器。m_vItem.begin() 会将迭代器初始化到向量的开头,并循环直到达到 m_vItem.end()。该代码还将项目添加到列表中。
删除 Vector 元素
std::vector<CItem>::iterator end; end = std::remove_if(m_vItem.begin(),m_vItem.end(),IsSelected); m_vItem.erase(end,m_vItem.end());
上述代码定义了 end 迭代器。remove_if 会删除 m_vItem.begin() 到 m_vItem.end() 范围内所有 IsSelected 谓词返回 true 的元素。erase() 函数会从向量中擦除所有已删除的对象。
IsSelected 是一个一元谓词。它接受一个参数(CItem 类型的对象)并返回 true 或 false。
结论
本文及其附带的示例项目对于所有刚接触 STL 的开发人员来说都是很好的参考。它也将解决即使是经验丰富的 STL 开发人员的一些基本问题。
参考文献
Herbert Schildt(C++ 完整参考)