STL 迭代器用法剖析

STL 中的迭代器有以下几种:输入迭代器、输出迭代器、正向迭代器、双向迭代器、随机访问迭代器。
1. 输入迭代器:一次只能读取一个元素,只能向前移动,支持:++、==、!=、(只读)
2. 输出迭代器:一次只能写一个元素,只能向前移动,支持:++、==、!=、(只写)
3. 正向迭代器:一次可以读写元素,只能向前移动,支持++、==、!=、(读写)
4. 双向迭代器:一次可以读写元素,能够双向移动,支持++、–、==、!=、(读写)
5. 随机迭代器:一次可以读写一个元素,支持正向、反向、任意位置移动。支持:++、–、==、!=、*(读写)、+=、+ -、-=、[]等

#include <iostream>
#include <vector>
#include <deque>
#include <forward_list>
#include <list>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
using namespace std;

1. 容器支持的迭代器

算法使用的迭代器种类是不同的,比如,有些算法要求迭代器类型必须是随机访问迭代器,那么,你的容器提供的是双向迭代器,就用不了这种算法。

void test01()
{
	// 1. vector 提供的迭代器是随机访问迭代器
	vector<int>::iterator it1;
	it1 += 5;
	
	// 2. deque 提供的迭代器是随机访问迭代器
	deque<int>::iterator it2;
	it2 += 5;

	// 3. forward_list 提供的是正向迭代器
	forward_list<int>::iterator it3;
	// it3 += 5;   // 语法报错
	it3++;
	// it3--;  // 语法报错

	// 4. list 提供的是双向迭代器
	list<int>::iterator it4;
	// it4 += 5;  // 语法报错
	it4++;
	it4--;

	// 5. set 提供的是双向迭代器
	set<int>::const_iterator it5;
	// it5 += 5;  // 语法错误
	it5++;
	it5--;

	// 6. unordered_set 提供的是双向迭代器
	unordered_set<int>::iterator it6;
	// it6 += 5; // 语法错误
	it6++;
	it6--;

	// 7. map 容器提供的是双向迭代器
	map<int, int>::iterator it7;
	// it7 += 5; // 语法错误
	it7++;
	it7--;

	// 8. unordered_map 提供的是双向迭代器
	unordered_map<int, int>::iterator it8;
	// it8+=5;
	it8++;
	it8--;
}

2. 迭代器辅助函数

  1. advance 函数:向前或者向后移动某个容器的迭代器到某个位置
  2. distance 函数:用于计算两个迭代器之间相差元素的个数
  3. iter_swap 函数:交换两个迭代器指向的元素的值
void test02()
{
	// 1. advance 函数:向前或者向后移动某个容器的迭代器到某个位置
	vector<int> v = { 10, 20, 30, 40, 50 };
	auto it1 = v.begin() + 3;

	list<int> l = { 10, 20, 30, 40, 50 };
	auto it2 = l.begin();
	//it2++;
	//it2++;
	//it2++;

	advance(it2, 3);

	// 2. distance 函数:用于计算两个迭代器之间相差元素的个数
	// 参数为两个迭代器区间,一般这两个迭代器都指向同一个容器
	distance(v.begin(), it1);

	// 3. iter_swap 函数:交换两个迭代器指向的元素的值
	// iter_swap(v.begin(), it1);
	iter_swap(v.begin(), it2);

	for (auto val : v) cout << val << " ";
	cout << endl;
}

template<class T>
ostream& operator<<(ostream& os, const vector<T>& vec)
{
	for (auto v : vec) cout << v << " ";
	return os;
}

template<class T>
ostream& operator<<(ostream& os, const deque<T>& vec)
{
	for (auto v : vec) cout << v << " ";
	return os;
}

3. 迭代器适配器

3.1 插入型迭代器

  1. 尾插型迭代器 back_inserter 支持的容器有 vector、deque、list 等有 push_back 函数的容器
  2. 头插迭代器 front_inserter 支持的容器有 deque、list、forward_list 等有 push_front 函数的容器
  3. 指定位置插入的迭代器 inserter 支持的容器有 vector、list 等有 insert 函数的容器
void test03()
{
	vector<int> v = { 10, 20, 30 };

	// 1. 尾插型迭代器(vector、deque、list)
	// back_inserter 函数可以获得某个容器的尾部插入迭代器
	back_insert_iterator<vector<int>> it1 = back_inserter(v);
	// it1 叫做尾部插入迭代器,对该迭代器的赋值操作,将会导致元素插入到容器尾部
	it1 = 100;
	*it1 = 200;
	cout << v << endl;
	// 注意:使用尾插迭代器,容器必须有 push_back 函数。

	// 2. 头插迭代器(deque、list、forward_list)

	deque<int> d = { 10, 20, 30 };

	// 使用 front_inserter 获得某个容器的头部插入迭代器
	front_insert_iterator<deque<int>> it2 = front_inserter(d);
	// 对该迭代器的赋值操作,将会导致元素添加到容器的头部
	it2 = 666;
	*it2 = 888;
	cout << d << endl;

	// 3. 指定位置插入的迭代器
	// 使用 inserter 函数获得该迭代器
	vector<int> v2 = { 10, 20, 30 };
	insert_iterator<vector<int>> it3 = inserter(v2, v2.begin() + 1);
	it3 = 111;
	*it3 = 222;
	cout << v2 << endl;
}

3.2 反向迭代器

reverse_iterator 适配器主要用于获得容器的反向迭代器。

void test04()
{
	vector<int> v = { 10, 20, 30 };

	// reverse_iterator<容器迭代器类型>
	// 指定位置:v.end 对于反向迭代器而言就是 30, 对于正向迭代器 30 后面的位置
	reverse_iterator<vector<int>::iterator> it(v.end());

	cout << *it << endl;
	cout << *(++it) << endl;
	cout << *(++it) << endl;
}

3.3 流式迭代器

输出流迭代器:

void test05()
{
	// 1. 输出流迭代器的使用
	ostream_iterator<int> it1(cout, "|");
	// 对 it1 这个输出流对象的赋值操作,都会导致将其输出到屏幕
	it1 = 100;
	*it1 = 200;

	// 2. 使用输出流迭代器将容器元素打印到屏幕上
	vector<int> v = { 10, 20, 30, 40, 50 };
	// copy(开始,结束,目标开始); 将前两个参数标定的区间赋值到第三个参数指定的容器中
	ostream_iterator<int> it2(cout, "|");
	copy(v.begin(), v.end(), it2);
	/*
		for(; first != last; ++first)
		{
			*dst = *first;
		}
	*/
}

输入流迭代器:

void test06()
{
	// 1. 输出入流迭代器使用
	// 输入需要标定开始输入、结束输入,所以需要创建两个对象
	// istream_iterator<int> first(cin);   // 将 cin 对象转换为迭代器对象
	// istream_iterator<int> last;  // 输入流结束迭代器对象

	// *first 表示要从迭代器获取数据,如果没有数据会等待数据。
	// 指向键盘输入的第一个数据
	//int v1 = *first;
	//cout << v1 << endl;

	// 表示获取下一个输入
	//int v2 = *(++first);
	//cout << v2 << endl;


	// 2. 通过输入流迭代器给容器赋值
	// 结束输入:ctrl + z

	vector<int> v2;
	v2.resize(10);  // 将大小变成10,并初始化10个对象

	istream_iterator<int> my_first(cin);
	istream_iterator<int> my_end;

	// copy 内部是赋值操作,目前 v2 中不存在元素,也没有空间,此时是不能赋值。
	copy(my_first, my_end, v2.begin());
	cout << v2 << endl;
}
未经允许不得转载:一亩三分地 » STL 迭代器用法剖析
评论 (0)

6 + 2 =