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

原创 2015年11月17日 17:31:38

    反向迭代器

    相信大家对正向迭代器应该都很熟悉,然而对于反向迭代器的使用确是有几处需要注意的地方,在此记录一下。先看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;

得到的输出如下

6
5
6

    反向迭代器删除元素

    所有的 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

版权声明:本文为博主原创文章,未经博主允许不得转载。

在遍历中使用 iterator/reverse_iterator 进行 Erase 的用法

众所周知,在使用迭代器遍历 STL 容器时,需要特别留意是否在循环中修改了迭代器而导致迭代器失效的情形。下面我来总结一下在对各种容器进行正向和反向遍历过程中删除元素时,正确更新迭代器的用法。首先,要明...
  • kesalin
  • kesalin
  • 2014年04月21日 20:02
  • 29734

STL 使用 erase 删除元素时 iterator 失效

STL中的容器按存储方式分为两类:一类是序列容器(如:vector,deque),另一类是关联容器(如:list,map,set)。 在使用erase方法删除元素时,有几点需要注意: 1) 对于...
  • hellokandy
  • hellokandy
  • 2016年08月26日 13:58
  • 1014

通过reverse_iterator的base()得到iterator

调用reverse_iterator的base成员函数可以产生“对应的”iterator。 vector v; v.reserve(5); for(int i = 0;i < 5; ++ i) { /...
  • ww32zz
  • ww32zz
  • 2015年08月14日 18:33
  • 957

effective stl 第26条:iterator优于const_iterator、reverse_iterator、及const_reverse_iterator

如果喜欢使用STL,但是对istream_iterator读取字符流的性能不很满意,那么istreambuf_iterator正是需要的工具。使用iterator的3个理由: 1、有些版本的eras...
  • u014110320
  • u014110320
  • 2016年09月24日 13:13
  • 435

vector::erase(iterator first, iterator last)使用须知

    今天使用了vector::erase删除函数,开始以为就是删除包括两个参数在内的元素,因为其它代码的关系,调试了一个多小时才知道是erase的问题,我们知道,要清除vector所有元素用cle...
  • pfjhbui
  • pfjhbui
  • 2008年07月03日 10:58
  • 1131

C++ vector容器erase操作后iterate失效真相

在使用STL Vector容器时,大家一定遇到进行erase操作后,迭代器会失效的现象。网上很多文章解释说,是因为Vector的底层是通过数组来实现的,erase之后会造成内存的重新分配,故原容器的迭...
  • chenfei0920
  • chenfei0920
  • 2015年07月23日 12:39
  • 650

C++ map 中的reverse_iterator

做了一个闽南师范大学OJ上的题,不想写排序,用了一下reverse_iterator,反向遍历容器 7006:学生成绩排序 Problem Description ...
  • u012662688
  • u012662688
  • 2016年05月29日 17:13
  • 1510

利用reverse_iterator删除string末尾元素

先看代码: #include #include using namespace std; int main() { string str = "Uranux~"; string::rev...
  • michaelalan
  • michaelalan
  • 2013年12月31日 21:53
  • 793

C++ STL容器中erase的使用

erase()函数的功能是用来删除容器中的元素 函数原型: iterator erase(iterator where); iterator erase(iterator first,i...
  • sszgg2006
  • sszgg2006
  • 2012年04月12日 14:11
  • 6045

c++ vector 在erase之后 保存iterator

在使用迭代器iterator遍历vector元素对其进行操作时, 删除元素时,后导致iterator所对应的元素发生变化, 需要对iterator的位置进行调整. 当删除的元素index在ite...
  • ziqian0512
  • ziqian0512
  • 2017年07月12日 20:32
  • 240
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:STL: reverse_iterator / iterator 关系以及 erase 相关(C++)
举报原因:
原因补充:

(最多只允许输入30个字)