STL的逆向迭代器

20 篇文章 0 订阅
2 篇文章 0 订阅

本文转自:http://zhouruijun163.blog.163.com/blog/static/10771562008111103635444/ 

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

STL的逆向迭代器reverse_iterator  - 小宝 - 征途 #include  < iostream >
STL的逆向迭代器reverse_iterator  - 小宝 - 征途#include 
< algorithm >
STL的逆向迭代器reverse_iterator  - 小宝 - 征途#include 
< vector >
STL的逆向迭代器reverse_iterator  - 小宝 - 征途
STL的逆向迭代器reverse_iterator  - 小宝 - 征途
using   namespace  std;
STL的逆向迭代器reverse_iterator  - 小宝 - 征途
STL的逆向迭代器reverse_iterator  - 小宝 - 征途
int  main()
STL的逆向迭代器reverse_iterator  - 小宝 - 征途
{
STL的逆向迭代器reverse_iterator  - 小宝 - 征途    vector
<int> col1;
STL的逆向迭代器reverse_iterator  - 小宝 - 征途    
for (int i=1;i<=9;++i)
STL的逆向迭代器reverse_iterator  - 小宝 - 征途        col1.push_back(i);
STL的逆向迭代器reverse_iterator  - 小宝 - 征途
STL的逆向迭代器reverse_iterator  - 小宝 - 征途    vector
<int>::iterator pos; 
STL的逆向迭代器reverse_iterator  - 小宝 - 征途    pos
= find(col1.begin(),col1.end(),5);
STL的逆向迭代器reverse_iterator  - 小宝 - 征途    cout
<<"pos:"<<*pos<<endl;
STL的逆向迭代器reverse_iterator  - 小宝 - 征途
STL的逆向迭代器reverse_iterator  - 小宝 - 征途    vector
<int>::reverse_iterator rpos(pos);
STL的逆向迭代器reverse_iterator  - 小宝 - 征途    cout
<<"rpor:"<<*rpos<<endl;
STL的逆向迭代器reverse_iterator  - 小宝 - 征途
STL的逆向迭代器reverse_iterator  - 小宝 - 征途    system(
"pause");
STL的逆向迭代器reverse_iterator  - 小宝 - 征途    
return 0;
STL的逆向迭代器reverse_iterator  - 小宝 - 征途}

STL的逆向迭代器reverse_iterator  - 小宝 - 征途

 

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

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

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

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


STL的逆向迭代器reverse_iterator  - 小宝 - 征途 explicit  __CLR_OR_THIS_CALL reverse_iterator(_RanIt _Right)
STL的逆向迭代器reverse_iterator  - 小宝 - 征途        : current(_Right)
STL的逆向迭代器reverse_iterator  - 小宝 - 征途        
{    // construct wrapped iterator from _Right
STL的逆向迭代器reverse_iterator  - 小宝 - 征途
        }

STL的逆向迭代器reverse_iterator  - 小宝 - 征途

 

有关_RanItcurrent的声明和定义如下:

STL的逆向迭代器reverse_iterator  - 小宝 - 征途 typedef _RanIt iterator_type;
STL的逆向迭代器reverse_iterator  - 小宝 - 征途
protected :
STL的逆向迭代器reverse_iterator  - 小宝 - 征途    _RanIt current;    
//  the wrapped iterator
STL的逆向迭代器reverse_iterator  - 小宝 - 征途
    };
STL的逆向迭代器reverse_iterator  - 小宝 - 征途
 

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


STL的逆向迭代器reverse_iterator  - 小宝 - 征途 reference __CLR_OR_THIS_CALL  operator * ()  const
STL的逆向迭代器reverse_iterator  - 小宝 - 征途        
{    // return designated value
STL的逆向迭代器reverse_iterator  - 小宝 - 征途
        _RanIt _Tmp = current;
STL的逆向迭代器reverse_iterator  - 小宝 - 征途        
return (*--_Tmp);
STL的逆向迭代器reverse_iterator  - 小宝 - 征途        }

STL的逆向迭代器reverse_iterator  - 小宝 - 征途

 

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

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

 

STL的逆向迭代器reverse_iterator  - 小宝 - 征途
Tag标签:  STL, 迭代器, reverse_iterator
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值