迭代器适配器和x适配器

1. 迭代器适配器

1.1 reverse_iterator 反向迭代器适配器

这个迭代器适配的作用是将迭代器逆转.
rbegin()rend()就是调用这个适配器, 如下图:
本来begin()迭代器++之后是往右边走的, 然后*运算符取的是迭代器右边的元素;
当使用rbegin()之后, rbegin()指向的地方和end()一样, ++是从右往左走, *运算符取的是迭代器左边的元素.
怎么会这么神奇呢? 这到底是怎么做到的呢?
具体实现下图右边代码告诉了我们结果.

分析:

  1. 当我们调用rbegin()时, 函数里面调用的是reverse_iterator(end()), 然后进入此类的构造函数
  2. 构造函数保存当前迭代器
  3. 当我们调用++时候, 类就会调用operator++操作符重载, 里面调用的是相反的操作: --
  4. 当我们调用*的时候, 类调用operator*, 里面做的操作是, 先--, 再取值*.

剩下各种操作都是类似手法.
在这里插入图片描述

1.2 inserter

这个inserter适配器的作用就是里面重载了=运算符, 分析同上:
在这里插入图片描述

2. X适配器

2.1 ostream_iterator

看如下代码, 可以用copy算法把容器里面的元素打印到终端.

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <set>
#include <iterator> //ostream_iterator

using namespace std;

void test01(){
    vector<int> my_vector;
    for(int i = 1; i < 10; ++i){
        my_vector.push_back(i*10);
    }
    ostream_iterator<int> out_it(cout, ",");
    copy(my_vector.begin(), my_vector.end(), out_it);
}
int main(int argc, char *argv[]){
    test01();

    return 0;
}

输出:

10,20,30,40,50,60,70,80,90,

以上操作是如何实现的呢?
看下图:

  1. 当我们调用copy的时候, 要注意copy里面执行的是=操作, 因此我们从这里下手, ostream_iterator就是这样做的
  2. ostream_iterator创建一个类, 类里面保存了cout和分隔符,, 等copy调用=时候, 便调用=重载, 在里面把value输出到cout去.
    在这里插入图片描述

2.2 istream_iterator

看如下代码:

void test01(){
    double value1, value2;
    cout << "please, insert two values: " << endl;
    istream_iterator<double> eos;
    istream_iterator<double> iit(cin);

    if(iit != eos){
        value1 = *iit;
    }

    ++iit;
    if(iit != eos){
        value2 = *iit;
    }

    cout << "value1: " << value1 << ", " << "value2 : " << value2 << endl;
}

上诉代码可以从终端接受2个输入, 放在value1和value2中. 这是怎么做到的呢?
那我们就要看一下istream_iterator类的代码了, 如下图右侧:

  1. 首先定义eos, 调用构造函数, 把0赋给in_stream
  2. 接着定义iit, 调用构造函数, 把cin赋给in_stream, 注意是引用, 然后构造函数里面做的事情是++*this. 因为++被重载过了, iit对象想调用++的话, 先用*this取对象, 然后调用++.
  3. 调用的过程是这样的: 进入++, 先判断in_stream是否为空, 因为cin不是空, cin是阻塞操作, 等待输入
  4. 然后等我们输入数字, 比如我们输入20 32, 这时候cin先从缓冲区读入20(因为cin内部处理不读入空格), 然后in_stream里面就有内容了(因为是引用), 之前在阻塞的函数就*in_stream>>value了, 然后iit的对象就创建成功了. 要注意的是, *in_stream>>value插入成功了, 返回的是true, 取反后是0, 所以不会执行in_steam=0
  5. 等我们执行value1 = *iit时候, 直接返回value
  6. 然后执行++iit, 继续进入前置++重载运算符函数中去, 继续把新的值写入value
  7. 下面执行就比较简单了.
    在这里插入图片描述

另外一个例子:
用copy, istream_iterator 以及inserter实现把容器的内容输入到cin:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zedjay_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值