Chinaunix首页 | 论坛 | 博客
  • 博客访问: 846996
  • 博文数量: 158
  • 博客积分: 4380
  • 博客等级: 上校
  • 技术积分: 2367
  • 用 户 组: 普通用户
  • 注册时间: 2006-09-21 10:45
文章分类

全部博文(158)

文章存档

2012年(158)

我的朋友

分类: C/C++

2012-11-26 15:54:24

template<typename T> struct foo;

template<class T> struct foo;
是等价的。
即告诉模板T是一种类型时,可以用class,也可以用typename。
这是因为C++标准一开始时都用class,后来发现typename这个关键字必不可少,于是有了重复功能。

template
struct foo
{
    T::type* type;
};
其中 T::type* type 是什么意思?编译器完全不知道,可能是
    T::type(T中一个静态成员变量名叫type) *(乘以) type(一个全局变量名)
也可能是
    T::type(T中定义的一个类型名叫type)*(指针形式) type
有歧义的话,编译就进行不下去了。于是得明确告诉编译器T::type是个类型,于是写成
template
struct foo
{
    class T::type* type;
};
如果T::type是个自定义的类型(class/struct皆可)那自然没问题,类似于
class cls {};
class cls obj; // 在C++中习惯省掉class,直接写成 cls obj; 在C中则必须加上
但假如是内建的int类型那就成了
class int obj;
所以到此必须引入关键字typename,告诉编译器后面是个类型名,不管它是自定义类型还是内建类型。正确的代码应该是
template
struct foo
{
    typename T::type* type;
};
总结一下,关键字typename就是告诉编译器后面是个类型,否则编译器优先认为它是一个“非类型”。
当然,在某些场合下,它不可能是一个“非类型”,即无歧义的场合中,typename是不可以加上的,例如:
struct X
{
    X( int )
    {
    }
};
struct Y
{
    typedef X type;
};
template struct foo : T::type
{
    foo() : T::type(0)
    {
    }
};

在(仅在)模板中,看起来似乎typename可以完全取代class,但看如下代码
template struct X
{
};
template< template class C > struct foo
{
};
foo a;
其中的class可以替换为struct和typename吗?自然不行,struct不像typename有作模板参数的功能,typename不像class/struct有作自定义类型的功能。

typename是用来消除歧义的,但有歧义的不仅是这一种,睇代码:
template struct B
{
    C::sub val;
};
其中 < 是 小于号,还是<>整体的前半部分?编译器优先认为是后者。
所以得在前面加上template告诉编译器C::sub是个模板。看一个复杂些的事例:
struct foo
{
    typedef int type;

    template
    struct sub
    {
    };
};

template struct B
{
    typename C::template sub<typename C::type> val;
};

int main()
{
    foo a;

    return 0;
}
C::type前要加typename,告诉编译器C::type是个类型名
sub前要加template,告诉编译器这是个模板,别当成是 小于号 和 大于号
C::template sub前要加typename,告诉编译器这是个类型。

自此文章结束,但某些用VC的人可能说:某些代码不加typename/template在VC中依然无错。这是因为VC对模板使用了“后编译”,看如下VC代码:
template struct foo
{
    foo()
    {
        C::sub val;
    }
};

struct A
{
    typedef int type;

    template
    struct sub
    {
    };
};

struct B
{
    static const int sub = 0;
    static const int type = 0;
};
int val = 0;

int main()
{
    foo a;
    foo b;

    return 0;
}
在foo
中 C::sub val; 是定义一个变量,在foo中是数值比较,好玩吧,当你在编写foo时,竟然不能确定其行为。

阅读(1303) | 评论(0) | 转发(0) |
0

上一篇:CRC16实现之一

下一篇:fstream的读写测试

给主人留下些什么吧!~~