42. Understand the two meanings of typename.

了解typename的双重意义

以下template声明中,class和typname有什么不同?

template<class T> class Widget;
template<typename T> class Widget;

从C++的角度而言,声明template参数时,不论使用关键字class或typname,意义完全相同。

然后C++并不总是把class和typename视为等价。有时候一定得使用typename。为了解其时机,我们必须先谈谈你可以在template内指涉的两种名称。

template内出现的名词如果相依于某个template参数,称之为从属名称。如果丛书名称在class内呈嵌套状,称之为嵌套从属名称。

对于下面代码:


template<typname C>
void print2nd(const C& container)
{
	C::const_iterator* x;
	...
}

看起来好像声明x为一个local变量,它是一个指针,指向一个C::const_iterator。

在知道C是什么之前,没有任何办法可以知道C::const_iterator是否是一个类型。而当编译器开始解析template print2nd时,尚未确知C是什么东西。C++有个规则可以解析此歧义状态:如果解析器在template中遭遇一个嵌套从属名称,它便假设这名称不是类型,除非告诉它是。所以缺省情况下嵌套从属名称不是类型。

一般性规则很简单:任何时候当你想要在template中指涉一个嵌套从属类型名称,就必须在紧临它的前一个位置放上关键字typename。

修改如下:

template<typname C>
void print2nd(const C& container)
{
	typename C::const_iterator* x;
	...
}

typename只能被用来验明嵌套从属类型名称;其他名称不该有它存在,例如下面这个function template,接收一个容器和一个“指向该容器的”迭代器:

template<typename C>
void f(const C& container, typname C::iterator iter);

C并不是嵌套从属类型名称,所以声明container时并不需要以typename为前导,但C::iterator是个嵌套从属类型名称,所以必须以typname为前导。

“typename必须作为嵌套从属类型名称的前缀词”这一规则的例外是,typename不可以出现在base classes list内的嵌套从属类型名称之前,也不可在member initialization(成员初值列)中作为base class修饰符。

请记住:

声明template参数时,前缀关键字class和typename可互换。
请使用关键字typename标识嵌套从属类型名称;但不得在base class lists(基类列)或member initialization list(成员初值列)内以它作为base class修饰符。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值