STL中迭代器是指针概念的泛化,共有六种:平凡迭代器(Trivial Iterator),输入迭代器(Input Iterator),输出迭代器(Output Iterator),前向迭代器(Forward Iterator),双向迭代器(Bidirectional Iterator),随机访问迭代器(Random Access Iterator)。
Trivial Iterator保证支持的操作最少,这些操作也是所有种类迭代器都支持的操作。包括: 默认构造 (Default constructor): Iterator x; 解引用取值 (Dereference): *x; 解引用赋值 (Dereference assignment): *x = t; 成员访问 (Member access): x->m; 等价于 (*x).m 相等比较 (Equality Comparable): x == y; 除去Trivial Iterator,最受限的迭代器是 Input Iterator和 Output Iterator,它们背后的模型是输入流和输出流模型。这两种迭代器除了支持Trivial Iterator的所有操作之外,还支持前向操作: 前置递增 (Pre-increment): ++x; 后置递增 (Post-increment): x++; 后置递增解引用 (Postincrement and dereference); *x++; 语义上等价于(实际上不一定是这么实现的) { Iterator y = x; ++x; return y; }。 然而,这两种迭代器只保证支持单程算法("single pass" algorithms),但不保证支持多程算法("multi-pass" algorithms)。我理解的意思是说,递增操作会改变流的内部状态,从而导致先前的迭代器失效。也就是说,下面的代码在实际运行中会有问题:{ Iterator y = x; ++x; *y; }。此外,Input Iterator和Output Iterator的差别在于,前者支持读操作(右值),后者支持写操作(左值)。也就是说对于Input Iterator来说,可以执行 { t = *x; } ,但不保证可执行 { *x = t; },相反,对于Output Iterator来说,可以执行{ *x = t; },但不保证可执行 { t = *x; }。 Forward Iterator 是对Input Iterator和Output Iterator的改进。它除了支持两者的所有操作之外,还支持允许多程算法作用其上。也就是说,它同时支持递增操作、读操作、写操作、多程算法。相当多的容器Iterator都是Forward Iterator,像map, set等等。 Bidirectional Iterator相当于在Forward Iterator上添加了递减操作,而且递减和递增是互逆的操作,包括: 前置递减(Pre-increment): --x; 后置递减 (Post-increment): x--; 所以才叫双向迭代器。像list这样的双向链表的迭代器就是Bidirectional Iterator。 最后, Random Access Iterator 支持指针的所有操作,是提供功能最多的迭代器:允许Iterator加上正或负的偏移、允许两个Iterator相减、允许两个Iterator比较大小等等。相对Bidirectional Iterator来说,新提供的操作包括: 迭代器加等常数 (Iterator addition): x += n; 迭代器加常数 (Iterator addition): x + n; 或 n + x; 迭代器减等常数 (Iterator subtraction): x -= n; 迭代器减常数 (Iterator subtraction): x - n; 求两迭代器的距离 (Difference): x - y; 元素取值 (Element operator): x[n]; 元素赋值 (Element assignment): x[n] = t; 小于比较 (Less): x < y; Random Access Iterator的例子有 vector, deque 的迭代器。 |