在STL中基本上都使用了模板类的声明,即template。在模板类的声明中,有两种方式:
template <class T>
template <typename T>
这里,class和typename是相同的。
也就是说,在声明模板类型参数的时候,class和typename意味着 完全相同的东西。
Effective C++ 中建议我们尽量使用typename而不是class来声明一个模板。因为class给人的感觉总像是T应该是一个类,或者说是用户自定义的类型,而typename则更像是表明T可以是任意一种类型。虽然在C++编译器看来,这两种声明方式没有任何的区别,其意义是完全一样的。
但是,在C++中,有的时候必须要使用typename,下面我们列举下面一个例子。关键字typename被用来作为类型之前的标识符号。
在这个 MyClass 模板中,ptr 是一个指针,其类型为 T::SubType*。 ptr 指向的是 T 类型中定义的 SubType 类型的对象。
在模板定义中,编译器默认不知道 T::SubType 是一个类型还是一个成员变量,因为在模板实例化之前,T 是未知的。使用 typename 告诉编译器 T::SubType 是一个类型。如果省略 typename,编译器可能会因为不明确而报错。T可以 是某个具体的类,它内部定义了 SubType 的类型。
如果要把一个template中的某个标识符号指定为一种类别,关键字typename不能省略。
C++的一般规则是,除了使用typename修饰之外,template内的任何标识符号都被视为一个值而不是一个类别(对象)。
无论何时,如果使用了一个依赖与模板参数的类型时,就必须在整个名字前加上typename。
嵌套类型是在一个类或结构体内部定义的类型。假设有一个类 A,在这个类内部,定义了另一个类 B 或者一个类型别名 B。这里的 B 就是一个嵌套在 A 内的类型,即 A 的嵌套类型。
在这个例子中,B 和 C 都是 A 的嵌套类型。