众所周知,大名鼎鼎的STL使用大量的模板,但是有时候我们也会面临一些需求,比如map或者vector里的数据类型被定义成模板,但这个时候,用起来就会出现问题。
我们先来看一个没有问题的例子:

/*===========================================================
#  Author:          DanteZhu – http://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;
}

程序运行结果如下:

win_1

但是如果我们想在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编译之后的结果如下:

win_2

可以看出,编译器没有认出 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;
}

运行结果如下:

win_3
OK,就这样啦,其实这种应用场景在程序中应用还是挺广的,不知道为什么C++编译器却无法支持。
(以上编译均由windows下g++编译)

版权所有,转载请注明出处.http://www.vimer.cn

C++模板的几个应用

C++的模板其实是个挺纠结的东西,用的不好的话,编译的一堆错误够你调到崩溃,但要是用的好呢,又确实非常方便,我们来看看 一.获取数组长度 比如 ...

阅读全文

vimer.cn原创vim(gvim)插件load_template正式发布

最近准备已久的模板载入插件 load_template 终于搞定了,现在正式放出下载大家使用.www.vim.org上已经放出了下载链接,如下: http://www.vim.org/scripts/sc...

阅读全文

8则回应给“关于map,vector中数据类型使用模板的问题”

  1. reg说道:

    map::iterator前需要typename让编译器知道它是某种类型

    [回复]

    Dante 回复:

    呃,朋友可否说的更详细一点?我也一直在寻找这种问题的更好的解决方法

    [回复]

    reg 回复:

    字符被过滤掉了,28行for循环里定义一个迭代的时候,迭代类型需要加typename关键字来指定它是一个类型,因为编译器不确定它是一个类型

    [回复]

    Dante 回复:

    果然如此!~~ 多谢啦~~~
    问题已经解决:
    在第二次的代码中,如下写法即可:
    for(typename map::iterator it = a->begin();it!=a->end();++it)

    [回复]

  2. mhsy2003说道:

    这个。。。。
    the c++ template一书中都有提到,你可以去看看。

    [回复]

    Dante 回复:

    ……呃,丢人了……,看来需要好好补习一下啦

    [回复]

    alexandercer 回复:

    记得c++ faq lite里面也有,不用看哪种大部头的c++template啦..

    [回复]

    Dante 回复:

    那本大部头也还没来得及看……果然我还是不到火烧眉毛是不会想翻书的……

    [回复]

发表评论