• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
onlyan
#define true false                  
博客园    首页    新随笔    联系   管理    订阅  订阅

STL reverse_iterator

在学习STL中关于迭代器reverse_iterator转换,发现个有趣的问题,如下例子。

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

int main()
{
    vector<int> col1;
    for (int i=1;i<=9;++i)
        col1.push_back(i);

    vector<int>::iterator pos; 
    pos= find(col1.begin(),col1.end(),5);
    cout<<"pos:"<<*pos<<endl;

    vector<int>::reverse_iterator rpos(pos);
    cout<<"rpor:"<<*rpos<<endl;

    system("pause");
    return 0;
}


 

输出的结果是:
Pos:5
Rpos:4
若将
pos= find(col1.begin(),col1.end(),5);
改为
pos= find(col1.begin(),col1.end(),3);
输出的结果是:
Pos:3
Rpos:2
 

rpos总是指向pos的前一个值,为什么呢?候捷先生译的《C++标准模板库》里是这么解释的:“注意,这不是bug,这是特性!导致这个行为的原因是区间的半开性。为了能够指定容器内所有元素,我们必须运用‘最后一个元素的下一位置’。”“逆向迭代器的设计者运用了一个小技巧:他们实际上倒置了‘半开原则’”

这两句话非常重要,首先容器的区间是左闭右开的,区间是以一个空位置作为区间的结束。对于逆向迭代器言,这个空位置就成了开始rbegin()的位置。但是这个位置上是没有值的,因此rbegin的值就取的是该位置前的一个值。--这正是“运用的小技巧”。这个小技巧保持了“以一个空位置作为区间结束”的原则。

 

说到转换,逆向迭代器用正向迭代器初始化,在转化过程中调用的是逆向迭代器的构造器,看下逆向迭代器的构造器的实现代码。注:代码在文件<xutility>中能找到(VC++8.0)。


 

explicit __CLR_OR_THIS_CALL reverse_iterator(_RanIt _Right)
        : current(_Right)
        {    // construct wrapped iterator from _Right
        }


 

有关_RanIt和current的声明和定义如下:

typedef _RanIt iterator_type;
protected:
    _RanIt current;    // the wrapped iterator
    };

 

从代码可以看出其实current是一个迭代器变量,在转换中它指向的正是正向迭代器。再来看看operator *的实现代码。


 

reference __CLR_OR_THIS_CALL operator*() const
        {    // return designated value
        _RanIt _Tmp = current;
        return (*--_Tmp);
        }


 

因此,从代码中可以知道,转换后逆向迭代器的实际位置(代码中的current)与正向迭代器的实际位置是保持一致的,而由于逆向迭代器在取值时迭代器位置向前减了1,即(*--_Tmp)。

书上有这样的译者注解:“‘将一个迭代器转化为逆向迭代器的过程中保持(履行)的是实际位置(元素)而非逻辑位置(数值)’,这句话的意思是,当pos转换为rpos,它们指向同一个实际地点,但它们所代表的意义(或说所代表的逻辑位置或数值)却变得不同了。”。从逆向迭代器的实现来看,书中所指的“实际位置”或“实际地点”,就是current。问题的原因结果就如下图表表。

 

STL <wbr>reverse_iterator

 

转载自:http://blog.sina.com.cn/s/blog_6294abe7010107rb.html

posted @ 2012-08-26 22:26  onlyan  阅读(1565)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3