typename的用法
很多人都会以为typename和class的作用是一样的,事实不然,typename还有另外一个用途:将某个带作用域的标识符显式地
说明为类型,这在类型之间具有依赖关系的情况下是经常要用到的。不好理解,先看个例子再说:
#include <iostream> using namespace std; template <class T> class TypeClass { public: typedef T Integer; }; template <class T> class TestClass { public: //T::Integer i; typename T::Integer i; //为什么一定要加typename? TestClass():i(6){} }; int main() { typedef TypeClass<int> IntegerType; typedef TestClass<IntegerType> UseInteger; UseInteger ui; cout<<ui.i<<endl; typedef TypeClass<double> DoubleType; typedef TestClass<DoubleType> UseDouble; UseDouble ud; cout<<ud.i<<endl; return 0; }
看上面的例子,在类模板TestClass中,T::Integet必须是一个类型,变量才有类型。此时类型Integet是依赖于类型T的。而我们也确实把一个类模板TypeClass作为参数传递给力TestClass,此时TestClass中的T就是一个TypeClass<int>,应该可以把
Integer解释为一个类型。但是,事实并不是这样,只有在类型T被实例化的时候,才能知道Integer是否为一个类型(因为Integer
既可以解释为一个成员变量,也可以解释为一个成员函数)。C++在默认的情况下,并不将依赖于别的类而存在的标识符认定为
类型,所以如果把typename T::Integer i中前面的typename去掉,就是发生编译错误。
总而言之,typename可以让编译器把它修饰的变量解释为一个类型,而不是一个函数。