迭代器和辅助函数



迭代器(iterator)是连接容器和算法的纽带,为数据提供了抽象,使写算法的人不必关心各种数据结构的细节。迭代器提供了数据访问的标准模型——对象序列,使对容器更广泛的访问操作成为可能。

根据迭代器所支持的操作不同,在STL中定义了如下5种迭代器:

迭代器类别 说明
输入 从容器中读取元素。输入迭代器只能一次读入一个元素向前移动,输入迭代器只支持一遍算法,同一个输入迭代器不能遍历一个序列两遍
输出 向容器中写入元素。输出迭代器只能一次一个元素向前移动。输出迭代器只支持一遍算法,同一输出迭代器不能两次遍历一个序列
正向 具有输入迭代器的全部功能和输出迭代器的大部分功能
双向 具有正向迭代器和逆向迭代器的功能,支持多遍算法
随机访问

具有双向迭代器的功能与直接访问容器中任何元素的功能,即可向前向后跳过任意个元素

迭代器的层次结构:

上面这图表并不是表明它们之间的继承关系:而只是描述了迭代器的种类和接口。


迭代器能力:

 

 

输入

输出

前向

双向

随机访问

读取(= *i)

 

×

写入(*i =)

 

×

多通

 

×

×

++ii++

 

--ii--

 

×

×

×

i[n]

 

×

×

×

×

i + ni - n

 

×

×

×

×

i += ni -= n

 

×

×

×

×

== !=

 

×

< >

 

×

×

×

×

<= >=

 

×

×

×

×


迭代器多通是指以同样的顺序来遍历容器,而且迭代器递增后,仍然可以通过解除保存的迭代器引用,来获得同样的值。


为何Forward迭代器不具备Output迭代器的全部功能?

这是因为有一个约束条件,使得某些对Output Iterator有效的程序对Forward Iterator可能无效。

  1. 面对Output Iterator无须检查其是否抵达序列尾端,便可直接写入数据。事实上由于Output Iterator不提供比较操作,因此无法将Output Iterator与end-of-sequence相比较。以下循环是正确的:
       while(true)
       {
        *pos = foo();
        ++pos;
       }
  2. 对于Forward Iterator,必须在提领数据之前确保其有效,因此上述循环对Forward Iterator是错误的。对于Forward Iterator上述循环应改为:
        while( pos != coll.end() )
       {
        *pos = foo();
        ++pos;
       }
     而同时,该循环不适用于Output Iterator,因为Output Iterator没有operator!=


*将迭代器移至“起点更前面或end()之后”都会引起未定义行为。


vecotr迭代器的递增和递减

迭代器的递增和递减操作有个奇怪的问题。一般而言你可以递增或递增暂时性迭代器,但对于vectors和strings就不行,如下:

        vector<int> coll;
	coll.push_back(1);
	coll.push_back(3);
	coll.push_back(2);
	coll.push_back(4);
	if (coll.size() > 1)
	{
		sort(++coll.begin(), coll.end()); //vs2013下能运行,因为实现为模板class
	}
	copy(coll.begin(), coll.end(), ostream_iterator<int>(cout, " "));

C++不允许你修改任何基本型别(包括指针)的暂时值,但对于struct和class则允许。因此如果迭代器被实作为一般指针,上面代码编译会失败。如编译不通过可以改为:

        vector<int>::iterator it = coll.begin();
        sort(++it, coll.end());



迭代器的辅助函数

#include<iterator>

void advance(InputIterator pos,int n);   

不检查迭代器是否超过end(), 无返回值。


#include<iterator>

iterator_traits<InputIterator>::difference_type distance(InputIterator pos1,InputIterator pos2);

两个迭代器都必须指向同一个容器,从pos1必须能到达pos2


#include<algorithm>

void iter_swap(ForwardIteraor1 pos1,ForwardIteraor2 pos2);

 迭代器型别不一定相同,但pos1和pos2的内容可相互赋值,交换迭代器pos1和pos2所指的值。



原文地址:https://www.cnblogs.com/ggzone/p/4052433.html