typename关键字:几乎令人忽略的typename

前言:

typename关键字是我们学习模板的时候,了解到的一个关键字。但在这几天之前,也仅仅是了解到有这个关键字,而几乎不用这个关键字。在个人看来,在template的参数中,由于class的存在这个简单的关键字,使typename变得有些暗淡。

而在这几天的一句代码中,才让我迫不及待的了解这个关键字。

这是一句什么代码呢?,让我们看正文!

typename关键字 

typedef typename Hash::hash_iterator<K, std::pair<K, V>, MapKeyofT<K, V>,Ha> iterator; 

在我不太了解typename关键字之前,也就是只知道在template参数中可以用typename,所以我写的代码是: 

 typedef      Hash::hash_iterator<K, std::pair<K, V>, MapKeyofT<K, V>,Ha> iterator; 

而这个时候,代码编译一直通不过 。

那么通不过的原因是什么呢?

在此之前我们需要了解一些概念。从属名称和非从属名称

//此处代码只是为了让大家了解概念
template <class T>
void vectorPrintf(vector<T>& arr)
{
   
   vector<T>::iterator it=arr.begin();
   while(it!=arr.end())
   {
       int x=*it;
       ++it;
       cout<<x<<endl;
   }

}

template内出现的名称如果依存于某一个template参数,称之为从属名称。

如果从属名称在class内称嵌套状,我们称它为嵌套从属名称  

一个并不依赖任何template参数的名称,这样的名称就是非从属名称

  it的类型是什么取决于template的参数T,则这就是一个从属名称,并且它还是一个嵌套名称。

x的类型为int,和template的参数没有任何关系,这就是一个非从属名称。

 我们再了解概念之后,直接给出typename的用处:

 typename 的用处:

  1.   用于声明template中的参数,从C++角度来看,无论使用typename还是class,意义都是相同的
  2.   typename被用来验明嵌套从属类型名称,其他名称不需要有它

template<class C>                        //声明template的参数,template和class意义相同,看个人习惯选择使用

void  Fun(C& container,             //非嵌套从属类型名称,不需要使用typename

typename  C::iterator   it)           //嵌套从属类型名称,一定要使用typename

 

用typename检验嵌套从属类型名称,这出于一种现状:嵌套名称有可能导致解析困难

C::iterator    *  x

我们看起来是申请了一个指针变量x 类型为C::iterator 。但是如果C中有个static变量命名为iterator,这句代码就和我们想的效果,相距十万八千里了,并且让我们感觉到这个世界太疯狂:两个变量进行相乘。

 

C++中有个规则,我们可以用这个理解一下,当解析器到这句代码的时候,不知道C::iterator是一个嵌套从属名称,怎么办呢?它就假设这不是一个类型,也就产生了我们刚才奇幻的一幕,被认为是两个变量相乘!而解决办法就是你告诉解析器这是一个嵌套从属名称,那么所遇到的问题也就迎刃而解了!

 

我们对于typename的认识到这里应该就完全OK了,但是这个世界总是有一些特别的事物,吸引着我们

请使用关键字typename表示嵌套从属类型名称;但不得在基类列表或者成员初始列表内以它作为基类的修饰符

template<class C>                        //声明template的参数,template和class意义相同,看个人习惯选择使用

class Derived : public Base<C>::xx      //基类列表,不允许使用typename

{

     Derived(int x)

     :  Base<C>::xx(x)

    {

         C& container                       //非嵌套从属类型名称,不需要使用typename

           Base<C>::xx    tmp                   //嵌套从属类型名称,一定要使用typename 

   }

 

}

让我们再次回顾一下typename

  • 用于声明template中的参数,从C++角度来看,无论使用typename还是class,意义都是相同的
  • 请使用关键字typename表示嵌套从属类型名称;但不得在基类列表或者成员初始列表内以它作为基类的修饰符

 

 

 

本文参考于Effective C++

注:如果本篇博客有任何错误和建议,欢迎伙伴们留言,你快说句话啊!

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值