一、引入
关键词typename 是C++标准化过程中被引入的,目的在于向编译器说明template 内的某个标识符是个类型(而不是其它什么东西)。考虑下面的例子:
template <typename T>
class MyClass {
typename T::SubType * ptr;
...
};
在这里,第一个typename可以换成class, 第二个 typename 关键词的意思是:SubType 是 class T 内部定义的一个类型,从而ptr是一个「指向 T::SubType 类型」的指针。
如果上例没有使用关键词 typename,SubType 会被认为是 class T 的一个 static 成员,于是被编 译器理解为一个具体变量或一个对象,导致以下式子:
T::SubType * ptr 所表达的意义变成:
class T 的 static 成员 SubType 与 ptr 相乘。
通常 如果 某个与 template parameter 相 关的名 称是个 类型( type) 时 ,你就 必须加 上关键 字 typename。
二、拓展:.template 构件 ( construct)
引入关键词 typename 之后,人们又发现了一个类似问题。考虑以下程序代码,其中使用标准的 bitset 类型:
template<int N>
void printBitset (std::bitset<N> const& bs) {
std::cout << bs.template to_string<char,char_traits<char>,allocator<char> >();
}
此例中的 .template 看起来有些古怪, 但是如果没有它,编译器无法得知紧跟其后的 "<" 代 表的是个 template argument list 的起始,而非一个「小于」符号。注意,只有当位于 "." 之前的 构件(construct)取决于某个 template parameter 时,这个问题才会发生。以上例子中,参数 bs 便是取决(受控)于 template parameter N。
结论是 ".template" 或 "->template" 记号只在 templates 之内才能被使用, 而且它们必须紧 跟着「与 template parameters 相关」的某物体。