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