- 一个小程序,使用不同类型迭代器做不同的事
|
|
- 调用例子
|
|
迭代器类型
- 模板参数类型In和Out分别作为输入迭代器和输出迭代器
- 支持相等(
==
/!=
)比较和++
自增操作符(前置/后置) 作为函数的参数被传递、返回、保存在数据结构中等
区别在于各自如何访问迭代器所代表的数据
- 通过一元操作符
*
支持间接引用
- 通过一元操作符
- 输入迭代器只需要能读取一个值
- 输出迭代器只需要能够赋值
*out = *in
必须按照预想工作,*in = *out
则不必
输出迭代器表示定位时都必须给迭代器赋一个值,且只能赋一次
输入迭代器增加到超过某个特定的输入值,那么这个值将再也不能被访问
虚拟序列
创建一个用来读取相同常量值序列的输入迭代器
设置数组的元素为某个特定值(把x的元素都设成0):
|
|
- c的行为类似指向一个无界“数组”的“指针”
|
|
缺省拷贝构造函数和赋值操作符
成员count跟踪产生的值的数量,比较操作符可以判断何时到达“序列”尾部
|
|
构造函数记住迭代器生成的值,解引用(dereference)操作符返回这个值
自增操作符递增遍历过的值的数目的计数
|
|
+
操作会把int对象增加增加到计数中,类似“哨岗”
|
|
- 当且仅当两个迭代器生成相同数量的值并且这些值都相等时这两个迭代器才相等
|
|
创建了一个迭代器,表示包含相等值的“虚拟数组”(实际上并不存在)
可以创建类似的起点和步长固定的迭代器
输出流迭代器
定义一个可以把值打印出来的输出迭代器(类ostream_iterator的一个对象)
ostream_iterator<int> out(cout)
*out++ = x;
打印x到cout上
ostream_iterator类设计构造函数设计为接受两个参数: ostream对象和const char*对象
|
|
- 用例: 将42重复10次打印到标准输出上
|
|
输入流迭代器
创建一个从某个istream中取值的输入迭代器
- 输入迭代器必须实现比较操作以判断是否到达文件尾部
- 进行尝试性地读取才能判断是否已经到达文件尾部,而读取值很耗费系统资源
“惰性读取”策略
- 每个istream_iterator对象有一个只能容纳一个元素的缓冲区和一个表明缓冲区是否已满的标志
- 另一个标志说明是否到达文件尾部
|
|
- 当且仅当buffer内有一个有用值时full为true
|
|
- 可以使用缺省的复制操作
- 自增操作符: 确保一旦迭代器遍历过一个值之后不会再读取这个值
|
|
必须预读以便判断是否到达文件尾部
惰性计算策略,首先检查是否需要输入,若需要则读取数据并适当地设置状态
|
|
- 只有当两个istream_iterator是同一个对象或者两者都处于文件尾部时才相等
|
|
- 将一个输入文件复制值到一个输出文件中去
|
|
Summary
- 看上去像指针的结构,容易被设想成仅仅是一个指针
深入研究某个算法使用到的指针操作会发现可以针对其他的数据结构模拟指针
istream_iterator和ostream_iterator类标准模板库的组成部分
- 而Constan_iterator不是(首字母大写)
《C++沉思录(Cplusplus Thinking)》笔记