c++学习笔记(七):再谈迭代器

容器一般都会提供一个迭代器,用于跟踪元素操作。  但是其实,标准库所定义的迭代器不依赖于特定的容器。 而容器所提供的迭代器也只是,标准库提供的一下三种迭代器的一种:
 
1 插入迭代器:  这类迭代器与容器绑定在一起,实现在容器中插入元素的功能

2 iostream 迭代器: 这类迭代器可与输入或输出流绑定在一起, 用于迭代遍历所关联的IO流
 
3 反向迭代器: 这类迭代器实现向后遍历, 而不是向前遍历。   所有的容器都定义了自己的reverse_iterator 类型,由 rbegin 和 rend 成员函数返回

迭代器的使用 都在iterator头文件中定义。

下面介绍,如何在泛型算法中 使用这些迭代器,  并如何利用const_iterator容器。以及总结5中迭代器



插入迭代器
一般有三种插入迭代器:
back_inserter  创建使用push_back实现插入的迭代器
front_inserter 使用push_front实现插入

这两个迭代器,都是接受一个容器实参的。

inserter  使用inserter 实现插入操作。  除了所关联的容器外,还接受第二个实参, 指向插入起始位置的迭代器。

   它们的用法:
   front_inserter与back_inserter的用法相同,都是在指定的地方插入元素
   
   inserter将产生在指定位置实现插入的迭代器:
    list<int>::iterator it = find(ilst.begin(), ilst.end(), 42):

     replace_copy(ivec.begin(), ivec.end(), inserter(ilst, it), 100, 0);

    这段代码的含义是: 在ilst中 在第一个出现42的地方,插入ivec中begin到end之间的元素,并将这一段元素中的100替换为0。

     inserter迭代器和copy及replace算法结合的用处是 ,  将一个容器中的元素插入到另一个容器中,并实现是否替换功能

 iostream 迭代器

   虽然iostream 不是容器。  但同样提供了迭代器:
   istream_iterator 用于读取输入流, 而ostream_iterator 则用于写输出流。   这些迭代器将它们所对应的流视为特定类型的元素序列。 
   使用流迭代器时,可以用泛型算法从流对象中读数据(或将数据写到流对象中)。
     
     iostream 迭代器的构造函数:
       istream_iterator<T> in(strm);  表示从输入流strm中读取T类型对象的istream_iterator对象。  
      istream_iterator<T> in; istream_iterator对象的超出末端迭代器
      ostream_iterator<T> in(strm);  解释同istream_iterator
      ostream_iterator<T> in(strm, delim);  创建T类型的对象写到输出流strm的ostream_iterator 对象, 在写入过程中使用delim作为元素的分隔符。delim是以空字符结束的字符数组
  
   流迭代器只定义了最基本的迭代器操作:自增、解引用和赋值。  此外,还提供了一些比较运算(相等或不等, 输出流则没有提供此类操作)。
  
   流迭代器的定义
     流迭代器都是类模板, 任何已定义的输入输出操作符(如>>)的类型(如cin)都可以定义 istream_iterator, 类似地可以定义ostream_iterator。

      在构造函数中的空格符必须是C风格字符串,因此该字符串必须以空字符结束, 否则, 其行为将是未定义的。

   istream_iterator对象上的操作:
    举个例子,便一目了然:
   istream_iterator<int> in_iter(cin);
   istream_iterator<int> eof;
  while(in_iter!=eof)
   vec.push_back(*in_iter++);

   其中while循环如何结束。  在这里,cin输入流是通过关联文件或输入来获得的,  当到达文件结尾或 输入的不是int 型数值 时, while停止

    ostream_iterator对象和 ostream_iterator对象的使用

  可使用ostream_iterator对象将一个值序列写入流中, 其操作的过程与使用迭代器将一组值逐个赋给容器中的元素相同:
  ostream_iterator<string> in_iter(cout, "\n");  表面以回车为间隔
   istream_iterator<string> in_iter(cin), eof;
   while(in_iter != eof)
     {
          *out_iter++ = *in_iter++;
     }

   看到这里,想到了文件输入输出操作,貌似有几分类似:
   ifstream infile;
   infile.open("in");
    
   ofstream outfile;
   oufile.open("out");
   即他们都要先申明是输入还是输出,  然后再绑定某一个文件/流。

    在类类型上使用 istream_iterator
    输出的流迭代器的解引用会立即 输出到指定的输数流上 或者屏幕或者文本。
     即利用类模板的性质, 流迭代器指向的元素和解引用的值都是该类类型。 然后 就可以通过流迭代器找到 该类的元素,通过该元素调用该类的成员
    
      一定要把流迭代器,想成存放很多输入输出的元素容器
    流迭代器的限制
     1 不可能从 ostream_iterator对象读入, 也不可能写到 istream_iterator对象中
     2  一旦给ostream_iterator 对象赋一个值, 写入就提交了。 赋值后, 没有办法再改变这个值。
     3 ostream_iterator没有->操作符

    与算法一起使用流迭代器:
    算法是基于迭代器操作实现的。
    流迭代器至少定义了一些迭代器操作。  由于流迭代器支持迭代器操作, 因此,至少可在一些泛型算法上使用这类迭代器。
    
   反向迭代器
   反向迭代器的使用与迭代器的使用完全是反过来的, 它通过定义一对反向迭代器(rbegin 和 rend)成员来完成。
   这样如果降序来排列vector, 只需向sort传递一对反向迭代器。

   反向迭代器与其它迭代器之间的关系
     如果要取出一行中  最后一个单词(这些单词以逗号分隔开)
     则 用反向迭代器查找 最后一个冒号(即方向的第一个冒号) 比较方便。
    然后利用 line.rbegin(), rcomma之间的单词。  但是这样的输出会导致 输出的单词字母都是颠倒的。    因此,为了纠正这个问题,我们必须把 rbegin() 和 rcomma转换为普通迭代器 ,然后再进行输出:
    其实,没必要转换line.rbegin(), 因为它必定对应的是 line.end(), 而对于rcomma, 只需调用多有反向迭代器类型都提供的成员函数 base 来 转换 rcomma即可。

    const迭代器:
     当我们不希望对迭代器的地址进行修改时, 可以使用它。  当用一些接受一对迭代器的算法或操作时, 必须使用匹配的const迭代器

    五种迭代器
    迭代器定义了常用的操作集, 但有些迭代器具有比其他迭代器更强大的功能。 例如, ostream_iterator 只支持自增、解引用和赋值运算。 而vector除了提供这些操作外,还提供自减、关系和算术运算。 因此,可以对迭代器进行分类。
     类似地,  还可根据算法要求它的迭代器提供什么类型的操作, 对算法进行分类。例如,find 只要求迭代器提供读取所指向内容和自增的功能。 另一些算法,如sort 则要求其迭代器有读、写和随机访问元素的功能。


       迭代器种类: 
        输入迭代器:  读, 不能写,只支持自增运算  
                还支持  相等和不等操作符,  解引用操作符,  箭头操作符
        输出迭代器: 写,不能读, 只支持自增运算
                还支持解引用, 而且每个迭代器的值必须正好输入一次,只能解引用一次。  一般用作算法的第三个实参。
        前向迭代器: 读和写, 只支持自增运算
             以一个方向遍历序列, 可以对同一个元素多次读写。 可复制前向迭代器来记录序列中的一个位置。 需要前向迭代器的泛型算法包括  replace
        双向迭代器:  读和写, 支持自增和自减运算
             从两个方向读写容器。双向迭代器包括前向迭代器的所有操作,除此之外, 还包括自减运算。
        随机访问迭代器:  读和写, 支持完整的迭代器算术运算

      需要低级类别迭代器的地方,可使用任意一种更高级的迭代器。  对于需要输入迭代器的算法, 可传递前向、双向或随机访问迭代器调用该算法。
     调用需要随机访问迭代器的算法是,必须传递随机访问迭代器。

       map和 set  关联容器的键是const对象,因此,关联容器不能使用任何写序列元素的算法。  只能使用与关联容器绑在一起的迭代器来提供用于读操作的实参。
 

  

 

    
      
     
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值