迭代器用于存取(access)一个序列(sequence)中的元素,其用法类似于指针。例如,我们可以用迭代器遍历一个向量(vector)的所有元素。
下列代码建立并使用与一个向量关联的迭代器:
vector<int> the_vector; vector<int>::iterator the_iterator; for( int i=0; i < 10; i++ ) the_vector.push_back(i); int total = 0; the_iterator = the_vector.begin(); while( the_iterator != the_vector.end() ) { total += *the_iterator; ++the_iterator; } cout << "Total=" << total << endl;
注意,我们可以通过解除迭代器引用(dereferencing, 即运算'*')存取容器的所有元素。
注:如果不想使用过去值,最好使用先增运算符(++iter),不使用后增运算符 (iter++)
后增运算符通常是如下实现的:
Iter operator++(int) { Iter tmp(*this); // store the old value in a temporary object ++*this; // call pre-increment return tmp; // return the old value }
显然,后增运算符效率不及先增运算符。
[编辑] 迭代器类型(Iterator Categories)
不同类型的迭代器功能也不一。读和写就需要使用不同的功能。
随机存取对于一个"vector"既高效的又方便的,但是,对于"list"是代价高的。
为此,根据其功能,迭代器被分为五类:
迭代器类型 | 描述 | 提供者 | 标签Tag |
---|---|---|---|
输入(Input) | 通过前移操作读取数据。 这种迭代器可以前移,可以比较,也可以解除引用。 | istream | input_iterator_tag |
输出(Output) | 通过前移动作写入数据。 这种迭代器可以前移,也可以解除引用。 | ostream, inserter | output_iterator_tag |
前向(Forward) | 通过前移操作读写数据。结合了输入迭代器和输出迭代器的功能,能够存储迭代器的值。 | slist | forward_iterator_tag |
双向(Bidirectional) | 通过前移操作和后移操作读写数据。这些迭代器类似于前向迭代器,但是,可以对其进行前移或者后移。 | list, map, multimap, set, multiset | bidirectional_iterator_tag |
随机存取(Random-access) | 随机读写数据,是功能最强的迭代器,结合了双向迭代器的功能,能够进行指针算术运算和指针比较运算。 | array, deque, string, vector | random_access_iterator_tag |
每个STL容器都关联一类迭代器,每个 STL 算法均使用一定类型的迭代器。
例如, 向量 的关联迭代器是随机迭代器,也就是说,向量可以使用需要随机迭代器的算法。因为随机迭代器具有其他类型迭代器的功能,所以,向量也可以使用为其他迭代器设计的算法。
vector<int> the_vector(10); // generate_n requires output_iterator generate_n(the_vector.begin(), 5, rand); // fill requires forward_iterator fill(the_vector.begin()+5, the_vector.end(), 100); // random_shuffle requires random_access_iterator random_shuffle(the_vector.begin(), the_vector.end()); // copy requires input_iterator copy(the_vector.begin(), the_vector.end(), ostream_iterator<int>(cout, " ")); // reverse_copy requires bidirectional_iterator reverse_copy(the_vector.begin(), the_vector.end(), ostream_iterator<int>(cout, " "));
[编辑] 辅助迭代器函数
头文件 <iterator> 定义了两个辅助函数。
void advance( input_iterator& pos, Dist n );
advance() 令 pos 前进(或后退) n个元素。
对于bidirectional和random_access_iterators,n 可以是表示后退的负数。
对于random_access_iterators, advance() 的执行时间是常数(只是调用pos+=n).
对于其他的迭代器, advance() 的执行时间是线性的(需要调用calls ++pos n 次).
typename iterator_traits<input_iterator>::difference_type distance( input_iterator pos1, input_iterator pos2 );
distance() 返回两个迭代器之间的距离。
对于random_access_iterators, distance() 的运行时间是常数 (只是返回 pos2 - pos1).
对于其他迭代器, distance() 的运行时间是线性的( 前移pos1 直至到达pos2, 然后返回前移操作次数).
[编辑] 失效迭代器(Invalidating Iterators)
当一个容器变化时,指向该容器中元素的迭代器可能失效。这使得在迭代器变化期间改变容器容易出现问题。在这方面,不同的容器提供不同的保障:
- vectors: 引起内存重新分配的插入运算使所有迭代器失效,插入也使得插入位置及其后位置的迭代器失效,删除运算使得删除位置及其后位置的迭代器失效.
- list/map: 插入不会使得任何迭代器失效;删除运算使指向删除位置的迭代器失效,但是不会失效其他迭代器.
Related topics: http:www.oreillynet.com/pub/a/network/2005/10/18/what-is-iterator-in-c-plus-plus.html