C++ 模板编程之typename用法

*例子来自《Effective  C++(第三版)》,模板编程主要是编译器在大发神威。

  1. 模板函数基础用法
  2. typename用法
  3. ……

typename一般用法

在展示上篇日志结尾的遗留的问题前,先来说明模板编程中template声明式中class和typename的关系。

“template声明式”中class和typename是等价的,不过个人倾向于在template声明式中使用typename,因为class关键词已经有声明或定义类这一用途了,这样可以作为区分。

什么是template声明式?就是如下的语句:

template<typename C>

typename的特殊用法

观察下面的代码,注意第5行和第6行的区别。

template<typename C>
void printAll(const C& container)
{
	//如果const_iterator为嵌套从属名称,需要添加typename关键字
	//C::const_iterator iter(container.begin());
	typename C::const_iterator iter(container.begin());
	for (; iter != container.end(); ++iter)
	{
		cout << *iter << " ";
	}
	cout << endl;
}

加不加typename有什么差别呢?

先来解释几个概念:

从属名称:template内出现的名称如果相依于某个template参数,称之为从属名称。

嵌套从属名称:嵌套从属名称是从属名称的子集,如果从属名称在class内呈嵌套状,我们称它为嵌套从属名称。还是有点绕口,在代码示例中,如果C是一个STL的容器类,那C::const_iterator既是从属名称,又是一个嵌套从属名称。实际上它是嵌套从属类型名称。

如上面所说,如果类型C是一个STL的容器类,那C::const_iterator无疑就是我们的迭代器类,但对于编译器来说,这是有歧义的,如果有某个自定义类恰巧也有一个叫做const_iterator的静态成员呢?我们写下这样的代码”C::const_iterator* x;“,是有歧义的,如果C::const_iterator是迭代器类,则" * "代表指针;但如果C::const_iterator是静态成员变量," * "代表乘法。很有可能在编译器中不报错,为了消除歧义,编译器优先将C::const_iterator解释为一个静态成员变量,如果C::const_iterator是一个嵌套从属类型名称,我们就要在语句前面加上typename关键词以示区分。

在模板类中,如果继承的基类是某个依赖template参数的类的嵌套从属类型,在继承语法构造函数列表中不必添加typename关键词,但在类中其他地方,包括构造函数函数体内就需要typename关键词,代码如下:

template<typename T>
class Derived:public Base<T>::Nested{//Base<T>::Nested前不要加typename
public:
    explicit Derived(int x):Base<T>::Nested(x)//Base<T>::Nested前不要加typename
    {
        typename Base<T>::Nested temp;//Base<T>::Nested要加typename
        ...
    }
}

提示:可能某些编译器的表现不和上面提到的一样。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值