// 具体请参考《Effective C++中文第三版》条款42::了解typename的双重意义
// 模板<template>
template内出现的名称如果相依于某个template参数,称为从属名称(dependent names);
如果从属名称在class内呈嵌套状,我们称它为嵌套从属名称(nested dependent name)。
// 一般性规则:任何时候当你想要在template中指涉一个嵌套从属类型名称,就必须在
// 紧邻它的前一个位置放上关键字typename。(有一个例外)
// 合法的C++代码
template<typename C>
void print2nd(const C& container)
{
if(container.size() >= 2 )
{
typename C::const_iterator iter(container.begin()); // C::const_iterator为嵌套从属名称, C为从属名称
...
}
}
// 不合法的C++代码
template<typename C>
void print2nd(const C& container)
{
if(container.size() >= 2 )
{
C::const_iterator iter(container.begin());
...
}
}
// typename必须作为嵌套从属类型名称的前缀词 这一规则的例外
// typename不可以出现在base classes list 内的嵌套从属类型名称之前,也不可在member initialization list (成员初值列)中作为base class 修饰符。
template<typename T>
class Derived:public Base<T>::Nested{ // base class list 中不允许“typename"
public:
explicit Derived(int x)
: Base<T>::Nested(x) // member initialization list 中不允许"typename"嵌套从属类型名称
{
typename Base<T>::Nested temp; // 即不在base class list中也不在mem.init.list中, 作为一个base class修饰符需要加上typename
...
}
例:
template<typename IterT>
void workWithIterator(IterT iter)
{
typedef typename std::iterator_traits<IterT>::value_type value_type;
value_type temp(*iter);
}
请记住:
1、声明template 参数时,前缀关键字class 和 typename 可互换
2、请使用关键字typename标识嵌套从属类型名称;但不得在base class lists(基类列)或member initialization list(成员初值列)内以它作为base class 修饰符.