众所周知,大名鼎鼎的STL使用大量的模板,但是有时候我们也会面临一些需求,比如map或者vector里的数据类型被定义成模板,但这个时候,用起来就会出现问题。
我们先来看一个没有问题的例子:
/*===========================================================
# Author: DanteZhu - https://www.vimer.cn
# Email: dantezhu@vip.qq.com
# FileName: tem.cpp
# Version: 1.0
# LastChange: 2010-01-12 10:20:07
# Description:
# History:
===========================================================*/
#include <iostream>
#include <string>
#include <vector>
#include <map>
using namespace std;
typedef struct _CTT
{
int len ;
}CTT;
template <typename T>
class CParse
{
public:
static int ComOne(map<int,T>* a)
{
T x;
x.len = 1000;
(*a)[100]=x;
}
};
int main(int argc,char* argv[])
{
map<int,CTT> a;
CParse<CTT>::ComOne(&a);
printf("%d\n",a[100].len);
return 0;
}
程序运行结果如下:
但是如果我们想在ComOne中进行对 a 的遍历,问题就出现了,代码如下:
#include <iostream>
#include <string>
#include <vector>
#include <map>
using namespace std;
typedef struct _CTT
{
int len ;
}CTT;
template <typename T>
class CParse
{
public:
static int ComOne(map<int,T>* a)
{
T x;
x.len = 1000;
(*a)[100]=x;
for(map<int,T>::iterator it = a->begin();it!=a->end();++it)
{
printf("[%d][%d]\n",it->first,it->second.len);
}
}
};
int main(int argc,char* argv[])
{
map<int,CTT> a;
CParse<CTT>::ComOne(&a);
printf("%d\n",a[100].len);
return 0;
}
F5编译之后的结果如下:
可以看出,编译器没有认出 map<int,T>::iterator 这个类型。
这个问题,困扰了我很长时间,最终也没有找到原因,但是已经找到了解决办法----即将 map<int,T>::iterator 再定义为一个新模板类型。
代码如下:
#include <iostream>
#include <string>
#include <vector>
#include <map>
using namespace std;
typedef struct _CTT
{
int len ;
}CTT;
template <typename T,typename E>
class CParse
{
public:
static int ComOne(map<int,T>* a)
{
T x;
x.len = 1000;
(*a)[100]=x;
for(E it = a->begin();it!=a->end();++it)
{
printf("[%d][%d]\n",it->first,it->second.len);
}
}
};
int main(int argc,char* argv[])
{
map<int,CTT> a;
CParse<CTT,map<int,CTT>::iterator>::ComOne(&a);
printf("%d\n",a[100].len);
return 0;
}
运行结果如下:
OK,就这样啦,其实这种应用场景在程序中应用还是挺广的,不知道为什么C++编译器却无法支持。
(以上编译均由windows下g++编译)
reg on #
map::iterator前需要typename让编译器知道它是某种类型
Reply
Dante on #
呃,朋友可否说的更详细一点?我也一直在寻找这种问题的更好的解决方法
Reply
reg on #
字符被过滤掉了,28行for循环里定义一个迭代的时候,迭代类型需要加typename关键字来指定它是一个类型,因为编译器不确定它是一个类型
Reply
Dante on #
果然如此!~~ 多谢啦~~~
问题已经解决:
在第二次的代码中,如下写法即可:
for(typename map<int,T>::iterator it = a->begin();it!=a->end();++it)
Reply
mhsy2003 on #
这个。。。。
the c++ template一书中都有提到,你可以去看看。
Reply
Dante on #
……呃,丢人了……,看来需要好好补习一下啦
Reply
alexandercer on #
记得c++ faq lite里面也有,不用看哪种大部头的c++template啦..
Reply
Dante on #
那本大部头也还没来得及看……果然我还是不到火烧眉毛是不会想翻书的……
Reply