条目二十八《正确理解由reverse_iterator的base()成员函数所产生的iterator的用法》
迭代器的种类一共有四种,上面已经说过了。这里就不再次写出来。
这一个条目主要是reserce_iterator和iterator的转换。可以使用base()函数来把前者转换为后者。
比如在拥有reserve_iterator,但需要用到插入,删除成员函数,那么这两个是不接受reserve_iterator作为参数的,所以需要转换为iterator再进行下一步的插入和删除元素。
以上代码得到的实际元素排布如下图:
首先应了解,通过base()得到的迭代器,只是把rbegin 和rend位置调换,然后整体向右移动一个地址。所以这样会造成调用base()迭代器指向的位置不一致,iterator会比reserve_iterator右移一位。
插入操作 这样在插入的时候,因为是在迭代器指向前插入新元素的,所以两种迭代器的结果是一样的。
删除操作 由于调用base()后的迭代器指向不一样,所以删除元素的结果是不一样的。
解决方法:
-
1.看起来“可行的”。
vertor
v; ... vector ::_revervse_iterator tr = find(v.rbegin(), v.rend(), 3); v.erase(--tr.bases());
这种方法在vwctor和string的时候有些stl实现会编译出错。因为它们的底层实现是迭代器是一根指针。
C和C++都规定了从函数返回的指针不应该被修改
- 2.最优的方法。
vertor
这种方法是,既然base()后你迭代器的指向后移一位,那么我就先往前一位再调用base(),这样得到的迭代器就是reserve_iterator和iterator的指向是一致的。
通过base()函数可以得到一个与reverse_iterator“相对应的”iterator的说法并不准确。对于插入操作,这种对应关系确实存在;但是对于删除操作,情况却并非如此简单。当你将一个reverse_iterator转换成iterator的时候,很重要的一点是,你必须很清楚你将要对该iterator执行什么样的操作,因为只有在此基础上,你才能够确定这个iterator是不是你所需要的iterator。