c++ | 五种 STL 迭代器

文章目录

      • 一、迭代器是什么?
      • 二、迭代器类别
        • 输入迭代器
        • 输出运算符
        • 前向迭代器
        • 双向迭代器
        • 随机访问迭代器
      • 三、不同容器所对应的迭代器类型
      • 四、迭代器的定义方式
      • 五、代码实现

一、迭代器是什么?

迭代器是一种抽象的设计理念,通过迭代器可以在不了解容器内部原理的情况下遍历容器。除此之外,STL 中迭代器一个最重要的作用就是作为容器与 STL 算法的粘结剂,只要容器提供迭代器的接口,同一套算法代码可以利用在完全不同的容器中,这是抽象思想的经典应用。

简单来讲,迭代器和 C++ 的指针非常类似,它可以是需要的任意类型,通过迭代器可以指向容器中的某个元素,如果需要,还可以对该元素进行读 / 写操作。

二、迭代器类别

常用的迭代器分为5个类别

  • Input itertor (输入迭代器) 只读;只支持自增运算
  • Output itertor(输出迭代器)只写;只支持自增运算
  • Forward itertor(前向迭代器)读写;只支持自增运算
  • Bidirectional itertor(双向迭代器)读写;支持自增和自减
  • Random access itertor(随机访问迭代器)读写;支持完整迭代器算数运算

输入迭代器

  • 输入迭代器可用于读取容器中的元素,但是不保证能支持容器的写入操作。输入迭代器必须至少提供下列支持。

  • 相等和不等操作符(==,!=),比较两个迭代器。

  • 前置和后置的自增运算(++),使迭代器向前递进指向下一个元素。

  • 用于读取元素的解引用操作符(*),此操作符只能出现在赋值运算的右操作数上。

  • 箭头操作符(->),这是 (*it).member 的同义语,也就是说,对迭代器进行解引用来获取其所关联的对象的成员。

  • 输入迭代器只能顺序使用;一旦输入迭代器自增了,就无法再用它检查之前的元素。要求在这个层次上提供支持的泛型算法包括 find 和 accumulate。标准库 istream_iterator 类型输入迭代器。

输出运算符

  • 输出迭代器可视为与输入迭代器功能互补的迭代器; 输出迭代器可用于向容器写入元素,但是不保证能支持读取容器内容。输出迭代器要求:前置和后置的自增运算(++),使迭代器向前递进指向下一个元素。

  • 解引用操作符(*),该引操作符只能出现在赋值运算的左操作数上。给解引用的输出迭代器赋值,将对该迭代器所指向的元素做写入操作。

  • 输出迭代器可以要求每个迭代器的值必须正好写入一次。使用输出迭代器时,对于指定的迭代器值应该使用一次 * 运算,而且只能用一次。输出迭代器一般用作算法的第三个实参, 标记起始写入的位置。 例如, copy 算法使用一个输出迭代器作为它的第三个实参, 将输入范围内的元素复制到输出迭代器指定的目标位置。标准库 ostream_iterator 类型输出迭代器。

前向迭代器

  • 前向迭代器用于读写指定的容器。这类迭代器只会以一个方向遍历序列。

  • 前向迭代器支持输入迭代器和输出迭代器提供的所有操作,除此之外,还支持对同一个元素的多次读写。可复制前向迭代器来记录序列中的一个位置,以便将来返回此处。需要前向迭代器的泛型算法包括 replace。

双向迭代器

  • 双向迭代器从两个方向读写容器。除了提供前向迭代器的全部操作之外,双向迭代器还提供前置和后置的自减运算(–)。
  • 需要使用双向迭代器的泛型算法包括 reverse。所有标准库容器提供的迭代器都至少达到双向迭代器的要求。

随机访问迭代器

  • 随机访问迭代器提供在常量时间内访问容器任意位置的功能。这种迭代器除了支持双向迭代器的所有功能之外,还支持下面的操作:

  • 关系操作符 <、<=、> 和 >=,比较两个迭代器的相对位置。

  • 迭代器与整型数值 n 之间的加法和减法操作符 +、+=、- 和 -=,结果是迭代器在容器中向前(或退回)n 个元素。

  • 两个迭代器之间的减法操作符(–),得到两个迭代器间的距离。

  • 下标操作符 iter[n],这是 *(iter + n) 的同义词。

  • 需要随机访问迭代器的泛型算法包括 sort 算法。vector、deque 和string 迭代器是随机访问迭代器,用作访问内置数组元素的指针也是随机访问迭代器。

  • 除了输出迭代器,其他类别的迭代器形成了一个层次结构:需要低级类别迭代器的地方,可使用任意一种更高级的迭代器。对于需要输入迭代器的算法,可传递前向、双向或随机访问迭代器调用该算法。调用需要随机访问迭代器的算法时,必须传递随机访问迭代器。

  • map、set 和 list 类型提供双向迭代器,而 string、vector 和 deque 容器上定义的迭代器都是随机访问迭代器都是随机访问迭代器, 用作访问内置数组元素的指针也是随机访问迭代器。istream_iterator 是输入迭代器,而ostream_iterator 则是输出迭代器。

  • C++ 标准为所有泛型和算术算法的每一个迭代器形参指定了范围最小的迭代器种类。例如,find(以只读方式单步遍历容器)至少需要一个输入迭代器。

  • replace 函数至少需要一对前向迭代器。replace_copy 函数的头两个迭代器必须至少是前向迭代器,第三个参数代表输出目标,必须至少是输出迭代器。

  • 对于每一个形参,迭代器必须保证最低功能。将支持更少功能的迭代器传递给函数是错误的;而传递更强功能的迭代器则没问题。

  • 向算法传递无效的迭代器类别所引起的错误,无法保证会在编译时被捕获到。

三、不同容器所对应的迭代器类型

  • array 随机访问迭代器
  • vector 随机访问迭代器
  • deque 随机访问迭代器
  • list 双向迭代器
  • set / multiset 双向迭代器
  • map / multimap 双向迭代器
  • forward_list 前向迭代器
  • unordered_map / unordered_multimap 前向迭代器
  • unordered_set / unordered_multiset 前向迭代器
  • stack 不支持迭代器
  • queue 不支持迭代器

四、迭代器的定义方式

尽管不同容器对应着不同类别的迭代器,但这些迭代器有着较为统一的定义方式
c++ | 五种 STL 迭代器_第1张图片

五、代码实现

#include
#include
using namespace std;
int main()
{
	vector<int> v{1,2,3,4,5,6,7,8,9};
	vector<int>::iterator it = v.begin();

	for(;*it != v.end();it++)
	{
		cout << *it <<"  ";
	}
	cout << endl;
	return 0;
}

你可能感兴趣的:(c++,容器,开发语言)