除了为每个容器定义的迭代器之外,标准库在头文件iterator中还定义了额外几种迭代器。这些迭代器包括以下几种:
绑定到容器中,用来向容器插入元素;
插入迭代器是一种迭代器适配器,接受一个容器生成迭代器,实现向给定容器添加元素。
相关的操作:
it= t; //在it指定位置插入值t
*it,++it,it++ //返回it
插入迭代器 | 说明 |
---|---|
back_inserter | 类似于使用c.push_back(val); |
front_inserter | 类似于使用c.push_front(val); |
inserter | 类似于使用 it = c.inserter(it,val);++it;元素被插入到给定迭代器之前的元素的地方 |
只有在容器支持push_ front(forward_list、list、deque)的情况下,我们才可以使用front_ inserter。类似的,只有在容器支持push_back(vector deque string)的情况下,我们才能使用back_ inserter.
样例:
vector strs = { "hhdy","ssssdfg","asdcfgd","hh","xx","hhdyzwhy" };auto it = inserter(strs, strs.begin()+1);it = "abs";//hhdy abs ssssdfg asdcfgd hh xx hhdyzwhyauto it1 = back_inserter(strs);*it1 = "hhh"; //it和*it=val都可以//hhdy abs ssssdfg asdcfgd hh xx hhdyzwhy hhhvector strs1;copy(strs.begin(), strs.end(), inserter(strs1, strs1.begin()));//hhdy abs ssssdfg asdcfgd hh xx hhdyzwhy hhhlist strs2;copy(strs.begin(), strs.end(), front_inserter(strs2));//hhh hhdyzwhy xx hh asdcfgd ssssdfg abs hhdyvector strs3;copy(strs.begin(), strs.end(), back_inserter(strs3));//hhdy abs ssssdfg asdcfgd hh xx hhdyzwhy hhhvector strs4;copy(strs.begin(), strs.end(), inserter(strs1, strs4.begin()));//hhdy abs ssssdfg asdcfgd hh xx hhdyzwhy hhh//此处和strs2进行对比,看看有什么不同。
虽然iostream类型不是容器,但标准库定义了可以用于这些IO类型对象的迭代器。istream_iterator 读取输入流,ostream_ iterator 向一个输出流写数据。这些迭代器将它们对应的流当作一个特定类型的元素序列来处理。通过使用流迭代器,我们可以用泛型算法从流对象读取数据以及向其写入数据。
操作 | 说明 |
---|---|
istream_iterator | in从输入流is中读取T类型的数据,in实际上相当于此段迭代器中的begin |
istream_iterator | 读取类型为T的istream_iterator尾后迭代器,相当于此段迭代器中的end |
in1 == in2 | in1和in2都是尾后迭代器或者绑定到相同的输入(前提二者都是读取T类型的数据) |
in1 != in2 | 非上面的描述即此描述 |
*in | 返回从流中读取的数据 |
in->mem | 等效于(*in).mem |
++in,in++ | 使用元素类型所定义的>>运算符从输入流中读取的下一个值。 |
常见用法1:
从cin读取int值存入vec
//从cin读取int值存入vecvector vec;istream_iterator int_it(cin),int_eof;while (int_it != int_eof) {vec.push_back(*int_it++);}//相当于下方代码istream_iterator in_iter(cin), eof;vector vec(in_iter, eof);
常见用法2:
从文件流读取string存入vecstr
ifstream in("文件地址");istream_iterator str_int(in),str_eof;vector vecstr;while (str_int != str_eof) {vecstr.push_back(*str_int++);}
常见用法3:
使用泛型算法操作流迭代器
istream_iterator intit(cin), inteof;cout<
可以对任何具有输出运算符(<<)的类型定义ostream_iterator。
ostream_iterator必须绑定到一个指定的流,不允许空的或表示尾后位置的ostream_iterator。
ostream_iterator 操作 | 说明 |
---|---|
ostream_iterator | out将类型T的值写入输出流os中 |
ostream_iterator out(os,d); | out将类型T的值写入输出流os中,每个值后都输出一个d。d指向一个空字符结尾字符数组。 |
out = val | 用<<运算符将val写入到out绑定输出流os中。 |
*out,++out,out++ | 不对out做任何事,返回out |
常用用法1:
输出
vector vec{ 1,2,3,4,5 };ostream_iterator out(cout, " ");for (int i : vec){out = i;//*out++ = i;//功能和上面的一致。}cout << endl;
常用用法2:
通过泛型函数打印输出
ostream_iterator out_iter(cout, " ");copy(vec.begin(), vec.end(), out_iter);cout << endl;
常用用法3:
使用流迭代器处理类:
待补。
反向迭代器是在容器从尾元素向首元素反向移动的迭代器。反向迭代器++it会移动到前一个元素,- -it会移动到后一个元素。
由于反向迭代器需要递减运算符,所以除单向链表和流迭代器外可以使用。
c.rbegin(),c.crbegin(),c.rend(),c.crend()
常用的方式1:
逆序输出:
vector vec = { 1,2,3,4,5 };ostream_iterator outer_vec(cout, " ");copy(vec.rbegin(), vec.rend(), outer_vec); //5,4,3,2,1cout<cout << *iter << " "; //5,4,3,2,1}cout << endl;
常用的方式2:
逆序排序:
sort(vec.rbegin(),vec.rend());
常用的方式3:
输出逗号分割列表中倒数第一个单词
由于普通迭代器是左闭右开,反向迭代器是左开右闭。二者不能混合使用。从一个普通迭代器初始化一个反向迭代器,或是给一个反向迭代器赋值时,结果迭代器和原迭代器指向的不是同一个元素。
可以使用reverse_iterator的base函数,使反向迭代器返回对应的普通迭代器。
string words = "hhdy,zwhy,hhdyzwhy";auto lword_iter = find(words.rbegin(), words.rend(), ',');cout << string(words.rbegin(),lword_iter) << endl; //yhwzydhh //为什么不用下面的那个格式呢?//原因在于lword_iter是从逆向过来的,所以他是一个反向迭代器,意味着他会反向的处理string,导致无限循环,在此处卡住。cout << string(lword_iter,words.rbegin())<
不拷贝其中元素,而是移动他们。