首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

const_reverse_iterator的疑问解决方案

2012-02-12 
const_reverse_iterator的疑问#includeiostream#includemapusingnamespacestdintmain(){map int,str

const_reverse_iterator的疑问
#include   <iostream>
#include   <map>
using   namespace   std;

int   main()
{
        map <int,string>   s1;
        s1.insert(make_pair(1, "sadf "));
        s1.insert(make_pair(2, "asdsadf "));
        map <int,string> ::const_reverse_iterator   i   =   s1.rbegin();
        for   (   ;i!=s1.rend();i++   )
                cout   < <   i-> first   < <   "   "   < <   i-> second   < <   endl;

        return   0;
}

编译时报错:
t2.cpp:   In   function   `int   main() ':
t2.cpp:11:   error:   no   match   for   'operator!= '   in   'i   !=   std::map <_Key,   _Tp,   _Compare,   _Alloc> ::rend()   [with   _Key   =   int,   _Tp   =   std::string,   _Compare   =   std::less <int> ,   _Alloc   =   std::allocator <std::pair <const   int,   std::string>   > ]() '

将上面的反向改为正向的(const_reverse_iterator=> const_iterator,   rbegin()   => begin(),rend()=> end())却没有问题,为什么?


[解决办法]
这个问题主要是由于s1不是个const对象,所以,s1.rbegin和s1.rend返回的都是reverse_iterator而非const_reverse_iterator。
像这样的
map <int,string> ::const_reverse_iterator i = s1.rbegin();
显式地把一个reverse_iterator转换成const_reverse_iterator,通过构造函数的模板参数的推导,没啥问题。
但后面的operator !=就可能问题了,原因是编译器可能找不到如何比较两个不同类型的iterator的方法,毕竟它们完全可能是两个没有关系的类,而且似乎VC的STL中也没有定义带有模板参数的operator!=,于是参数推导也无从谈起。

解决的办法之一可以是,先把rend的const_reverse_iterator版本给弄出来:
#include <iostream>
#include <map>
#include <string>
using namespace std;

int main()
{
map <int,string> s1;
s1.insert(make_pair(1, "sadf "));
s1.insert(make_pair(2, "asdsadf "));
map <int,string> ::const_reverse_iterator i = s1.rbegin();
map <int,string> ::const_reverse_iterator iend = s1.rend();
for ( ;i!=iend;i++ )
cout < < (i-> first) < < " " < < (i-> second) < < endl;

return 0;
}

最后,你后面的用到了string的输出,可能还得
#include <string>
[解决办法]
还有种方法是先取得一个指向s1的const指针或引用,然后从它上面调用rbegin和rend,就不会有问题了。

const map <int, string> & s2 = s1;
map <int,string> ::const_reverse_iterator i = s2.rbegin();
for ( ;i != s2.rend(); i++ )
cout < < (i-> first) < < " " < < (i-> second) < < endl;
[解决办法]
刚刚看了一下VC中map的源码,发现:
map的const_iterator和iterator都明确定义了operator !=(VC STL里map中的iteartor还是从const_iterator派生下来的,呵呵),编译器可赖以做模板推导。

但map的reverse_iterator和const_reverse_iterator,分别是:std::reverse_iterator(map::iterator)和std::reverse::iterator <map::const_iterator> 。(语法不对,姑且让我这样表示一下意思),也就是两个适配出来的东西。
而std::reverse_iterator偏偏没有定义operator!=(它的父类也没有),它们仗着自己只有一个简单的成员,去让编译器产生默认的operator==(及与之相反的operator!=)来用。
结果当两个不同的类出现在一起时,编译器不知道咋办了。
[解决办法]
增加#include <string> 后,VC2005编译通过
------解决方案--------------------


effective stl item 26/27

热点排行