typename关键字详解(消除歧义)

typename关键字详解

文章目录

  • typename关键字详解
    • 定义
    • 用法
      • 1.和class同义,用于引入泛型编程中所用到的模板参数
      • 2.用来消除歧义,告诉编译器后面的是类型名而不是变量名

定义

typename相当于泛型编程中class的同义关键字,用来指出模板类型所依赖的名称是类型名而非变量名

变量名:int bar 中 bar是变量名,int是类型名

typedef int bar :bar 也是类型名,是类型int的别名

用法

1.和class同义,用于引入泛型编程中所用到的模板参数

// 定义一个返回参数中较大者的通用函数
template 
const T& max(const T& x, const T& y)
{
  return x > y ? x : y;
}

等价于

template 
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 
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 
void foo(const T& t)
{   
    // 声明一个指向某个类型为T::bar的对象的指针
    typename T::bar * p;
}

这样就确定了p为一个指向bar类型的指针,不会出现歧义

你可能感兴趣的:(C++修习之路,开发语言,c++)