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