STL: reverse_iterator / iterator 关系以及 erase 相关(C++)

来源:互联网 发布:淘宝 3d试衣 编辑:程序博客网 时间:2024/05/16 14:35

    反向迭代器

    相信大家对正向迭代器应该都很熟悉,然而对于反向迭代器的使用确是有几处需要注意的地方,在此记录一下。先看STL源码处注释如下:

  /**   *  Bidirectional and random access iterators have corresponding reverse   *  %iterator adaptors that iterate through the data structure in the   *  opposite direction.  They have the same signatures as the corresponding   *  iterators.  The fundamental relation between a reverse %iterator and its   *  corresponding %iterator @c i is established by the identity:   *  @code   *      &*(reverse_iterator(i)) == &*(i - 1)   *  @endcode   *   *  <em>This mapping is dictated by the fact that while there is always a   *  pointer past the end of an array, there might not be a valid pointer   *  before the beginning of an array.</em> [24.4.1]/1,2   *   *  Reverse iterators can be tricky and surprising at first.  Their   *  semantics make sense, however, and the trickiness is a side effect of   *  the requirement that the iterators must be safe.  */

也即两者相差一个元素,从一个反向迭代器获得对应的正向迭代器需要使用 base() 方法,如下图应该可以清楚阐明两者的关系

                                                 

即:如果 ri 为指向元素 3 的反向迭代器,则调用 base() 方法 i = ri.base() 得到的将是指向元素 4 的正向迭代器 i 。

    vector<int> vec = {1, 2, 3, 4, 5, 6};    vector<int>::reverse_iterator rfirst = reverse_iterator<vector<int>::iterator>(vec.end());    vector<int>::reverse_iterator rlast = reverse_iterator<vector<int>::iterator>(vec.begin());    vector<int>::reverse_iterator rsecond = next(rfirst);    cout << *rfirst << endl;    cout << *rsecond << endl;    cout << *(rsecond.base()) << endl;

得到的输出如下

656

    反向迭代器删除元素

    所有的 erase 函数都只接受正向迭代器 iterator,所以如果想在反向遍历删除元素时必须要将 reverse_iterator 转换为 iterator 后再执行 erase 操作,所以反向迭代器与正向迭代器相差 1 的这个细节在这里必须要考虑清楚。比如按上图 ri 指向元素 3,但转换为正向迭代器后实际为指向元素 4 的位置,为了能正确执行删除,必须先将反向迭代器前进 1 步再转为正向迭代器。

    vector<int> vec = {1, 2, 3, 4, 5, 6};    for(auto rit = vec.rbegin(); rit != vec.rend();){        if(*rit % 2 == 0){            vec.erase((++rit).base());        }else{            ++rit;        }    }    for(auto& x : vec)        cout << x << " ";

输出结果为

1 3 5

0 0