在非模板代码中,我们可以这么写

1
string::size_type

编译器有 string 的定义,因此会知道 size_type 是表示一个类型,而不是 static 数据成员

但是对于模板代码中,T::size_type 会产生歧义。由于编译器会默认通过作用域运算符访问的名字不是类型,形如:

1
T::size_type * p;

会被认定成变量 p 和类型 T 中的静态成员 size_type 的乘积,然而程序员可能想表达的是,使用 T 中的类型成员 size_type 声明一个指针 p

为了避免这种歧义,就需要显式指明这个名字是一个类型

1
typename T::size_type *p;

使用如下:

1
2
3
4
5
template<typename T>
typename T::value_type TestFunction(const T& C)
{
return typename T::value_type();
}

上边代码中,实现了一个模板函数,返回了一个默认初始化的 T::value_type 类型的变量

综上,如果期望通知编译器一个名字表示一个类型时,就必须使用关键字 typename