众所周知,大名鼎鼎的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

STL可能的误用-find_first_of和erase

一.string中find_first_of的误用 STL中提供的string可以说极大方便了对字符串的操作,但是很多函数由于样子上很相似,所以导致很容易理解错误,find_first_of...

阅读全文

关于哈希map奇慢无比的原因定位

最近有一个server在重启的时候总要花费5分钟左右来加载配置文件,导致外网服务不可用,今天和几个同事一起研究了一下,总算找到了问题所在. 抽象出代码如下: ...

阅读全文

在C++中实现foreach循环,比for_each更简洁!

python,c#,java里面都有类似于foreach的结构,stl里面虽然有for_each这个函数,但是感觉使用还是太繁琐了一些,所以就自己实现了一个。 先来看看stl里面的for...

阅读全文

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 回复:

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

    [回复]

发表评论