【Effective C++】typename 双重含义

含义一:模板声明


template 的声明式中,可以使用 class 或者 typename,如下:

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

在这里,classtypename 没有任何不同,个人倾向于使用 typename,避免与类型声明的 class 混淆。


含义二:声明嵌套从属名称类型变量


假设现在有这样一个模板函数,传进来一个模板容器,希望打印出容器内的第二个元素:

template<typename C>
void print2ndElement(const C& container) {
	if (container.size() > 2) {
		C::const_iterator iter(container.begin());
		++iter;
		int value = *iter;
		std::cout << value;
	}
}

乍一看没有什么问题,那么我们考虑假设有另外一种实现:

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

看起来好像是声明了一个局部变量 x,指向 C::const_iterator。它之所以会被这样认为,是因为我们心里已经默认了 C::const_iterator 代表一个类型。但是有没有可能 C::const_iterator 并不是一个类型呢?
有!!
如果恰巧 C 中有一个静态变量,就命名为 const_iterator
如果 x 恰巧是一个 global variale;
那么,上面那句话就变成了 C 中的静态变量 const_iterator 与 全局变量 x 的相乘动作!
人间惊奇!!
虽然这个事情发生的概率极低,但是确认仍然有可能的,C++解析器必须关心模板类、模板函数所有可能的输入。
所以,如果 C++ 解析器在 template 中遇到了一个嵌套从属名称,它会假设这个名称不是一个类型,除非你告诉它是。我们必须用 typename 关键字,来告诉解析器,这个嵌套名称是一个类型。 有一个例外下面会说明。

所以最开始的代码应该修改为:

template<typename C>
void print2ndElement(const C& container) {
	if (container.size() > 2) {
		typename C::const_iterator iter(container.begin());	//加上 typename
		//...
	}
}

嵌套从属名称就是那些在类中定义的别名,比如:
vector<int>::iterator
std::iterator_traits<vector<int>::iterator>::value_type


例外


typename 必须作为嵌套从属名称的前缀词 这个规则的例外是,typename 不能出现在 base class 内的嵌套从属名称之前,也不能出现在成员初始化列表中作为 base class 的修饰符,如下面所示:

template<typename T>
class Derived : public Base<T>::Nested{				//不允许加 typename
public:
	explicit Derived(int x) : Base<T>::Nested(x){	//不允许加 typename
		typename Base<T>::Nested temp;				//必须加 typename
	}
}

typedef 定义别名


对于下面这种较长的类型定义:

template<typename IterT>
void wordWithIterator(IterT iter){
	typename std::iterator_traits<IterT>::value_type temp;
	//..
}

每次定义这种类型时,都必须写那一大串,这个时候应该考虑用用 typedef 关键字定义别名:

template<typename IterT>
void wordWithIterator(IterT iter){
	typedef typename std::iterator_traits<IterT>::value_type value_type;	//定义别名
	value_type temp;
	//..
}

这个时候,每次可以直接使用 value_type 定义变量,简洁!

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值