两种方式都可以在模板中使用,但是它们有什么区别呢
我们都知道,在 STL 中基本上都使用了模板类的声明,即 template. 在模板类的声明中,我们有两种方式:
1 | template <class T> |
在这里,class 和 typename 是相同的。也就是说,在声明一个 template type parameter (模板类型参数) 的时候,class 和 typename 意味着
完全相同的东西.
但是,在 C++ 中,有的时候必须要使用 typename. 下面我们列举下面一个例子.
关键字 typename 被用来作为型别之前的标识符号.
1 | template <class T> |
在这里,typename 指出 SubType 是 class T 中定义的一个类别,因此 ptr 是一个指向 T::SubType 型别的指针。如果没有关键字 typename, SubType 会被当成一个 static 成员,于是
1 | T::SubType * ptr |
会被解释为型别 T 内的数值 SubType 与 ptr 的乘积.
SubType 成为一个型别的条件是,任何一个用来取代 T 的型别, 其内部必须有一个内部型别 (inner type) SubType 的定义。例如,将型别 Q 当作 template 的参数.
MyClass x;
必要条件是型别 Q 有如下的内部型别定义:
1 | class Q{ |
因此,MyClass 的 ptr 成员应该变成一个指向 int 型别的指针,子型别 SubType 也可以成为抽象
数据型别(例如,class):
1 | class Q{ |
注意,如果要把一个 template 中的某个标识符号指定为一种类别, 就算是意图显而易见,关键字 typename 也是不能省略的,因此 C++ 的一般规则是,除了使用 typename 修饰之外,template 内的任何标识符号都被视为一个值而不是一个类别 (对象).
总结:
- template
与 template 一般情况下这两个通用, 但有一个特例,就是当 T 是一个类,而这个类又有子类 (假设名为 innerClass) 时,应该用 template : - typename T::innerClass myInnerObject; 这里的 typename 告诉编译器, T::innerClass 是一个类,程序要声明一个 T::innerClass 类的对象, 而不是声明 T 的静态成员,而 typename 如果换成 class 则语法错误.