typename关键字详解
定义
typename相当于泛型编程中class的同义关键字,用来指出模板类型所依赖的名称是类型名而非变量名
变量名:int bar 中 bar是变量名,int是类型名
typedef int bar :bar 也是类型名,是类型int的别名
用法
1.和class同义,用于引入泛型编程中所用到的模板参数
// 定义一个返回参数中较大者的通用函数
template <typename T>
const T& max(const T& x, const T& y)
{
return x > y ? x : y;
}
等价于
template <class T>
const T& max(const T& x, const T& y)
{
return x > y ? x : y;
}
2.用来消除歧义,告诉编译器后面的是类型名而不是变量名
我们先定义两个结构体:
struct StructWithBarAsType
{
typedef int bar;//bar 位类型名
};
struct StructWithBarAsValue
{
int bar;// bar为变量名
};
然后来看下面这段代码:
template <class T>
void foo(const T& t)
{
// 声明一个指向某个类型为T::bar的对象的指针
T::bar * p; //能得到我们想要的结果吗???
}
int main()
{
StructWithBarAsType x;
foo(x);
StructWithBarAsValue y;
foo(y);
}
这段代码是有问题的,因为编译器并不清楚bar是什么:
- bar可能是像第一个结构体中,是一个类型名,此时p是指向bar类型的指针
- bar也可能是第二个结构体中,作为一个变量名,此时foo( )不会将 * 作为指针的标志,而是将其看为乘号,实现bar*p
此时就出现了歧义,在C++中,编译器默认bar为变量名,如果作为类型名,需要在前面加上typename
template <typename T>
void foo(const T& t)
{
// 声明一个指向某个类型为T::bar的对象的指针
typename T::bar * p;
}
这样就确定了p为一个指向bar类型的指针,不会出现歧义