正在加载……
专注、离线、切勿分心
迭代器:
迭代器类似于指针,用以指示容器中的某个元素。
迭代器本质:
1、模板的引入使得函数和类定义脱离了存储类型的限制,在需要时指定即可,是一种泛化的思维观念,这使得算法独立于类型迭代器是种更高层次的抽象,它使得算法独立于容器。
2、迭代器是种类型,在程序中使用的是其对象。从迭代器的层面上看,对所有类型容器元素的访问应该是等价的,因此,迭代器对象应具备以下功能:
      ——间接访问(*p),即deference,在迭代器类中必须对一元*操作符定义。
      ——迭代器对象之间的赋值,如  p=q,在迭代器类中必须对赋值操作符定义。
      ——迭代器对象间的比较,比较两个迭代器是否相等,因此,在迭代器类内必须对关系运算符  ==     !=   进行定义,原则上讲,不需要对迭代器进行大小比较(<、>)等,就像比较指针实际上是比较其中存储的地址大小一样,没有意义。
      ——能使用迭代器遍历容器中所有的元素,在本章已给出的示例代码中已经大量应用了诸如“p++”之 类的操作,因此,在迭代器类必须对前缀增1后缀增1进行定义。
 



迭代器类型:
不同的算法对迭代器的要求不同,为此,STL定义了5种迭代器,分别是:
随机访问迭代器    (RandomAccessIterator)
双向迭代器          (BidirectionalIterator)
前向迭代器          (ForwardIterator)
输出迭代器          (OutputIterator)
输入迭代器          (InputIterator)
其层次结构如所示:
为什么要定义这么多迭代器:
1、不同的算法要求的迭代器类型不同,之所以定义了5种迭代器,是为了使用“最合适”的工具,编写算法时在满足要求的基础上尽可能地使用功能少的迭代器,减少迭代器引入的副作用,假设要编写一个查找函数 find(),只要能读取容器中的元素即可,最理想的方案是使用输入迭代器,这样,有效防止了在find()函数内对元素的修改,真正“物尽其用”。
2、图13.1:箭头左侧的迭代器不仅都实现了右侧迭代器所有的功能,而且在其基础上增加了一些功能。所以说,箭头左侧的迭代器“适应”于箭头右侧的迭代器,因此,如果某个算法的形参为前向迭代器,则实参可以是双向迭代器和随机访问迭代器,但不能是输出迭代器或输入迭代器。

7种容器迭代器的具体类型:
1、vector和deque是随机访问迭代器,其他5种均为双向迭代器
2、7种容器迭代器p均支持如下操作: *p读,*p写,++p,p++,--p,p--
3、只有vector和deque迭代器p支持如下操作:p += n 和 p -= n
        




流迭代器:
1、流迭代器是特殊的迭代器,包括两种:
     ——输出流迭代器(ostream_iterator)
     ——输入流迭代器(istream_iterator)
2、理解的要点是将输入/输出流作为容器看待。因此,任何接受迭代器参数的算法都可以和流一起工作。使用流迭代器必须要包含头文件  #include<iterator>
 
输出流迭代器(ostream_iterator)
1、输出流迭代器的定义为:
        ostream_iterator<class T1, class T2=char> 迭代器名(ostream_type &ost, const T2 *p=0);
2、如:
        ostream_iterator<int> osi(cout, "\n");
3、现在osi就是一个输出流迭代器,通过osi可使用cout输出int类型的数据,结束符为换行符

输入流迭代器(istream_iterator)
1、输出流迭代器的定义为:
        istream_iterator<class T1,class T2=char> 迭代器名(istream_type& ist);
2、如:
        istream_iterator<int,char> isi(cin);
3、现在isi就是一个输入流迭代器,通过isi可使用cin接收int数据类型的键盘输入,结束符为非数字字符。

#include <iostream>
#include <iterator>
#include <vector>
using namespace std;
int main()
{
        vector<int> vecInt = {1,2,3,4,5,6};
        ostream_iterator<int,char> osi (cout," ");    //创建输出流迭代器osi,osi相当于容器
        cout<<endl;
        copy(vecInt.begin(),vecInt.end(),osi);    //vecInt复制到流中,copy是泛型算法
        cout<<endl;
        return 0;
}
#include <iostream>
#include <iterator>
#include <vector>
using namespace std;
int main()
{
        vector<int> vecInt;
        istream_iterator<int> isi(cin);                   //创建输入流迭代器isi
        //istream_iterator<int,char> isi(cin);         //默认结束符是char,可以省略
        copy(isi,  istream_iterator<int>(),  back_inserter(vecInt));
  //将输入流插入到容器中
        //copy(isi,istream_iterator<int,char>(),back_inserter(vecInt));
        for(auto & elem : vecInt)
                cout<< elem <<" ";
        cout<<endl;
        return 0;
}




posted on 2018-05-13 09:10  正在加载……  阅读(197)  评论(0编辑  收藏  举报