当前位置:   article > 正文

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

typename

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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

等价于

template <class T>
const T& max(const T& x, const T& y)
{
  return x > y ? x : y;
}
  • 1
  • 2
  • 3
  • 4
  • 5

2.用来消除歧义,告诉编译器后面的是类型名而不是变量名

我们先定义两个结构体:

struct StructWithBarAsType
{
    typedef int bar;//bar 位类型名
};  
  • 1
  • 2
  • 3
  • 4
struct StructWithBarAsValue
{
    int bar;// bar为变量名
};
  • 1
  • 2
  • 3
  • 4

然后来看下面这段代码:

template <class T>
void foo(const T& t)
{
    // 声明一个指向某个类型为T::bar的对象的指针
    T::bar * p;		//能得到我们想要的结果吗???
}

int main()
{
    StructWithBarAsType x;
    foo(x);
    
    StructWithBarAsValue y;
    foo(y);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

这段代码是有问题的,因为编译器并不清楚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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/576888
推荐阅读
  

闽ICP备14008679号