最后更新于 .

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

程序运行结果如下:

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++编译)

 

Pingbacks

Pingbacks已打开。

Trackbacks

引用地址

评论

  1. reg

    reg on #

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

    Reply

    1. Dante

      Dante on #

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

      Reply

      1. reg

        reg on #

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

        Reply

        1. Dante

          Dante on #

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

          Reply

  2. mhsy2003

    mhsy2003 on #

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

    Reply

    1. Dante

      Dante on #

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

      Reply

      1. alexandercer

        alexandercer on #

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

        Reply

        1. Dante

          Dante on #

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

          Reply

发表评论