五种不同类型的iterator不用的功能,是各自 重载了相应功能的操作。。
Iterators (迭代器 范型指针)
iterator 是用来指向其他对象的 对象. 当我们将该iterator加1 . 它就指向区间内的下一个对象;
2.3.1 Input Iterators
* 当它作为一般的指针时. 有3种不同的特点: 它是可取值的. 可跨越尾端的. 可为NULL的.
* 可以比较两个Iterator对象的相等性.
* Input Iteraotr 对象之间可以赋值. 可以拷贝.(在参数中的iterator传递的是值时调用)
* 可以取值(operator*)
* 可以做++运算. (包括前缀的和后缀的)
其他特点:
* Input Iterator 只提供取对象的值. 但并不一定可以对取出的对象赋值(例如const int *)
* 虽然可以++ . 但并不一定有 -- 操作符.
* 虽然重载 == 但象 > 等其他的比较运算符并不一定支持.
* 它只能遍历区间 [first , last) 一次.并对区间中的值最多读取一次.(例如从终端读取输入.取出一个值则该值从输入流就删除了)
可以看出. Input Iterator 的功能受到很多的限制. 所以这种迭代器只能用在接受该类迭代器的算法.
例如: find find_if equal partial_sum random_sample set_intersection 等.
2.3.2 Output Iterators
Output Iterator的特点:
* 和Input Iterator一样. 可以拷贝和赋值OutputIterator.
* 可以通过Output Iterator来对其所指对象赋值. 如 *p = x;
* 可以累加 ++
它的限制和Input Iterator也类似.
* 如只支持++ 而没有 --
* 不能让两个Output Iterator指向区间里两个不同的地方.
* 只可以写向所指对象. 但不能读取. 如 x = *p 是不行的.
看看ostream_iterator的定义:
template<class T> class ostream_iterator{
private:
ostream *os;
const char* string;
public:
ostream_iterator(ostream& s, const char *c=0) : os(&s), string(c) {}
ostream_iterator(const ostream_itrerator& i): os(i.os),string(i.string){}
ostream_itreator& operator=(const ostream_iterator& i){
os = i.os;
string = i.string;
return *this;
}
ostream_iterator<T> & operator= (const T& value) {
*os << value;
if (string) *os << string;
return *this;
}
ostream_iterator<T>& operator*() {return *this;}
ostream_iterator<T>& operator++() {return *this;}
ostream_iterator<T>& operator++(int) {return *this;}
};
这就是一个"只写"的迭代器;
2.3.3 Forward Iterators
上面的"只读"和"只写"的迭代器有很多限制.例如:
*不能同时读和写.
*只能对区间遍历1次.
*在一个区间同一时刻只能有一个迭代器访问.
例如下边的replace算法就不能用这两个迭代器.它用newValue替换oldValue:
template<class ForwardIterator , class T> //它要既读又写.所以不能用上面两个
void replace( ForwardIterator first, ForwardIterator last,
const T&oldValue, const T& newValue){
for(; first != last; ++first)
if (*first == oldValue) *first = newValue;
}
再例如查找中的另一种需要. 搜索序列中相邻且相等的元素.也不能用上两个迭代器:
template <class ForwardIterator> //Input_Iterator不允许两个迭代器同时访问区间.所以不能用.
ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last){
if(first == last) return last;
ForwardIterator next = first;
while (++next != last) {
if(*first == *last) return first;
first = next;
}
return last;
}
所以我们引入Forward Iterator .它支持的运算与Input_Iterator Output_Iterator同级.(只有++没有--或p+=3等)
但没有上面列出的三个限制了.它可以用在上面两种迭代器可以出现的地方.
2.3.4 Bidirectional Iterators
上面的Forward Iterators有一个重要的限制: 它只能++ 不能-- .而Bidirectional Iterators则添加这个功能.所以它可以
用在上边三种迭代器出现的地方.
这在有些算法里是不行的.比如遍历双向链表的时候就需要用 Bidirectional Iterators.
考虑下边的算法reverse_copy. 它反序拷贝一个区间的元素到另一个区间:
template <class BidirectionalIterator first, BidirectionalIterator last, OutputIterator result){
while (first != last){
-- last; //首次递减前. last指向序列后的下一个位置.
*result = *last;
++ result;
}
return result;
}
2.3.5 Random Access Iterators(随机访问迭代器)
上面的四个迭代器都只是提供了指针运算的一个子集而已. 第四个Bidirectional Iterator也只是增加了指针-- 的运算.
要完全模拟指针的行为.需要引入第五个迭代器类型 Random Access Iterators.
它涵盖了指针的所有运算: 加法减法(p+数字, p-数字). 下标(p[n]). 两个Iterator相减(p1 - p2). 以及前后次序比较(p1<p2).
它可以用在上面4种迭代器出现的地方.
这对类似sort这样的算法很重要. 因为排序算法必须有能力比较并交换相隔的元素(而不只是相邻的元素).