1.当声明模板类型参数时,class和typename的意义相同。
2.模板内出现的名称如果依赖于某个模板参数,称为从属名称(dependent names);如果从属名称在类中呈嵌套状,称为嵌套从属名称。
嵌套从属名称有可能导致解析困难,如:
template<typename C> void print2nd(const C& container){ C::const_iterator* x; //可能是在声明一个迭代器,也有可能是在做一个乘法运算 ... }
C++关于解析这种歧义的规则是:如果解析器在模板中遭遇一个嵌套从属名称,它便假设这名称不是个类型,除非显式声明它是。这一规则有一例外:typename不可以出现在基类列表内的嵌套从属类型名称之前,也不可在成员初始化列表中作为基类的修饰符。显式声明的方法是在前面加上typename关键字:
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 ... } ... };
注意typename只是用来表示嵌套从属类型,非嵌套从属类型不应该有它存在。
3.当涉及的typename声明式太长时,可以使用typedef:
template<typename IterT> void workWithIterator(IterT iter){ typedef typename std::iterator_traits<IterT>::value_type value_type; value_type temp(*iter); ... }
4.typename相关规则在不同的编译器上有不同的实现方式,因而关于它的使用可能造成移植性的降低。