再探迭代器

本文详细介绍了C++标准库中的四种特殊迭代器:插入迭代器、流迭代器、反向迭代器和移动迭代器。解释了每种迭代器的功能及应用场景,并通过示例代码展示了如何使用这些迭代器进行高效的数据操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

除了为每个容器定义的迭代器以外,标准库在头文件 iterator 中还定义了额外4种迭代器

插入迭代器流迭代器反向迭代器移动迭代器


插入迭代器

基本介绍

插入器是一种迭代器适配器,接受一个容器,生成一个插入迭代器

vector<int> vi;
auto it = back_inserter(vi);
//back_inserter是插入器
//it是其生成的对应容器vi的插入器

对插入器赋值的时候,会自动向容器中添加元素

*it = 100;                     //将100插入vi尾部(插入类型由插入器决定)
cout<<vi.size()<<" "<<vi.front()<<endl;
//输出       1 100

插入迭代器定义了几种操作

*it = t;                //在it指定位置插入值为t的元素,具体位置由插入器决定
/*--------*/
*it;                //定义了这些操作,但不做任何事情,统一返回it
it++;

插入器的类型

  • back_inserter

    总是向容器的末尾插入元素

vector<int> v1={1,2,3,4},v2;

auto back_it = back_inserter(v2);
copy(v1.begin(),v1.end(),back_it);
//v2中为 1 2 3 4
  • front_inserter

    总是向容器的头插入元素

auto front_it = front_inserter(v2);
copy(v1.begin(),v1.end(),front_it);
//v2中为 4 3 2 1
//每次插入前都会更新插入位置确保总是在头部插入
//插入1后,容器的头就会重定位在1之前,所以2会插在1之前,以此类推
  • inserter

    接受第二个参数:插入位置,第二个参数是一个指向给定容器的迭代器,元素将插在这个迭代器表示的元素前面
    ※ 插入的位置是静态的,创建时就确定,只会向那个位置插入元素

auto front_it = inserter(v2,v2.begin());
copy(v1.begin(),v1.end(),front_it);
//v2中为 1 2 3 4

inserter插入图解

由于插入位置是绑定不变的,所以插入位置的迭代器一旦失效就会造成异常

vector<int> v(10);                  //v有10个元素
auto it = inserter(v,v.end());      //v.end()在当前容器末尾,第10个元素后面
*it = 1;                            //ok
v.resize(5);                        //将容器大小缩小为5,原容器超过5的部位被删除
*it = 2;                            //触发异常,原来的位置已经被删掉

反向迭代器

 位置和操作

  • 位置

首 vec.begin()
尾后 vec.end()
———反———
首前 vec.rbegin()
尾 vec.rend()
反向迭代器的位置


  • 操作

    递增(++)、递减(- -)操作符的作用也反过来了
    方向迭代器使用++从后向前遍历,使用- -从前往后遍历

反向迭代器需要递减运算符

forward_list流迭代器 没有反向迭代器

反向迭代器与普通迭代器转换

  • 用普通迭代器初始化反向迭代器
string str = "hello, world, hello, cpp.";
auto punct_it = find(str.begin(), str.end(), ',');      //普通迭代器
string::reverse_iterator re_it(punct_it);   //用普通迭代器punct_it初始化re_it
cout << *punct_it << " " << *re_it << endl;
//输出  , o

反向迭代器和普通迭代器并不指向同一个位置

  • 反向迭代器返回普通迭代器

    调用base成员函数

    string str = "hello, world, hello, cpp.";
    auto re_it = str.rend();   //反向迭代器 首前
    auto it = re_it.base();    //获取普通迭代器,同样位置改变了
    cout << *it << endl;
    //输出  h

上面两个例子可以看出,普通迭代器和反向迭代器它们所指的元素是不同的
这样的设计思路是:普通迭代器与反向迭代器的目的是表示元素范围,而一个约定俗成的规定是用 左闭右开 区间来表示一个范围 ,把开始的方向称为左,结束的方向称为右
这里写图片描述


流迭代器


移动迭代器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值