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. 迭代器辅助函数
- advance 函数:向前或者向后移动某个容器的迭代器到某个位置
- distance 函数:用于计算两个迭代器之间相差元素的个数
- 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 插入型迭代器
- 尾插型迭代器 back_inserter 支持的容器有 vector、deque、list 等有 push_back 函数的容器
- 头插迭代器 front_inserter 支持的容器有 deque、list、forward_list 等有 push_front 函数的容器
- 指定位置插入的迭代器 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;
}

冀公网安备13050302001966号