typename的双重意义

文章讲述了C++中class和typename在template声明中的区别,尽管它们在基本语法上无异,但typename用于解决嵌套从属类型可能导致的解析歧义。通过实例说明了typename的必要性及其使用方法。
摘要由CSDN通过智能技术生成

首先来看下面一个问题:
在template声明中,使用class和typename有什么不同?
template<class T>class Widget;
template<typename T>class Widget;
抛开使用习惯,声明template参数时,单从C++本身的角度来看,使用关键字class或typename没有任何不同。

但是C++并不是把它们完全视为等价,因为存在既有价值,如果完全一样,干嘛费劲的搞了两个出来呢,一个岂不是更方便。
在这里你要知道,有时候你必须使用typename。
我们先来看下面这个函数模板例子:

template<typename T>
void print(const T& container)
{
	if(container.size()>=1)
	{
		T::const_iterator iter(container.begin());
		int value=*iter;
		std::cout<<value;
	}
}

这个模板函数的功能是接收一个STL容器为参数。然后将容器中的第一个元素打印出来。
看起来没什么问题,编译也能通过,如果你亲自测试的话,也会发现能够运行良好。但是在某些极端情况下,呵呵,会发生什么呢?
我们先来看一个概念:
T::const_iterator
iter的类型是T::const_iterator,但是实际上iter是什么是取决于T。
而const_iterator这个名称的具体含义也是依赖于T的,我们将它称为从属名称。T::const_iterator这个整体是一个嵌套,我们称它为嵌套从属类型名称。因为const_iterator是从属于T的。
嵌套从属名称可能导致解析困难。我们看下面的代码

template<typename T>
void print(const T& container)
{
	T::const_iterator* m;
	...
}

这里我们声明m为一个局部变量,它是一个指向T::const_iterator的指针。
但是有一种情况,如果T::const_iterator它不是一个类型,而是T中的一个静态成员变量(确实有这个可能),而这时m碰巧也是一个全局变量(哪有这么巧的事呀!),那上面的代码就不是定义一个指针变量了,而是两个静态变量相乘。
上面的情况虽然特殊,但确实有可能发生的。所以C++解析器的设计者必须考虑如何避免这个问题。
C++有个规则可以解析这一歧义状态:如果解析器在模板中遇到这个嵌套从属名称,它便假设这个名称不是一个类型。除非你明确告诉他。在缺省情况下,嵌套从属名称不是类型。

template<typename T>
void print(const T& container)
{
	if(container.size()>=1)
		T::const_iterator iter(container.begin());
		...
}

上面这段程序不是有效的C++代码。iter只有在T::const_iterator是一个类型时才合理,但是我们并没有明确告诉C++,所以它默认它不是一个类型。
要想告诉C++,明确指定它是一个类型很简单,在前面加上一个typename就行了

template<typename T>
void print(const T& container)
{
	if(container.size()>=1)
	typename T::const_iterator iter(container.begin());
	//明确指定是一个类型
		...
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

辣椒种子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值