C++ 迭代器(Iterators)


迭代器用于存取(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)通过前移操作读取数据。 这种迭代器可以前移,可以比较,也可以解除引用。istreaminput_iterator_tag
输出(Output)通过前移动作写入数据。 这种迭代器可以前移,也可以解除引用。ostream, inserteroutput_iterator_tag
前向(Forward)通过前移操作读写数据。结合了输入迭代器和输出迭代器的功能,能够存储迭代器的值。slistforward_iterator_tag
双向(Bidirectional)通过前移操作和后移操作读写数据。这些迭代器类似于前向迭代器,但是,可以对其进行前移或者后移。list, map, multimap, set, multisetbidirectional_iterator_tag
随机存取(Random-access)随机读写数据,是功能最强的迭代器,结合了双向迭代器的功能,能够进行指针算术运算和指针比较运算。array, deque, string, vectorrandom_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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值