typename

1. //在C++中typename一般用来声明模板的模板参数(template parameter):
   template<typename T> class X;   //T是一个模板参数
   
2. /*但是还有一个关键的用法。首先是两个概念:
   1). qualified name
       例如:std::cout, std::endl;这样含有作用域符号(::)的就是限定名,
       当我们用using声明将cout,endl引入到当前作用域之后就可以直接使用
       这两个名称,这个时候cout,endl就不是限定名了。
   2). dependent name
       dependent name是依赖于模板参数的类型,例如:*/
       template <typename T> class X
       {
           int i;
           std::vector<int> ivec;
           std::vector<int>::iterator iter;
           
           T type;
           std::vector<T> tvec;
           std::vector<T>::iterator titer;
       };
       /* 前3个成员变量是不依赖于模板参数,所以是non-dependent name,后3个是dependent name
       ,直到实例化该模板的时候才会知道到底是什么类型。*/
       
   //下面来讨论typename的第二种用法。现在假设我们有一个类如下:
   template <typename T> class Y
   {
       T::iterator *iter;
       ...
   };
   /* 我们可能本意是想定义一个迭代器对象,例如我们如果用vector<int>来实例化这个模板,那么iter
   则应该是一个迭代器指针,但是,如果我们用下面这个类来实例化这个模板:*/
   class cType
   {
       static int iterator;
       ...
   };
   /* 那么T::iterator *iter会被编译器解释为两个数相乘。事实上,C++编译器会采用第二种解释方法
   ,即使iterator的确是一个类型名。
   为了避免这种矛盾,当我们适用qualified dependent name的时候,需要用typename来指出这是一个
   类型名.即: */
   template <typename T> class Y
   {
       typename T::iterator *iter;
       typedef typename T::iterator iterator; //定义了Y::iterator类型名称
       ...
   };
   //typename 指出下面紧跟着的名称是一个类型

 

还有一个模板解析的:

typename<typename Iter>

typename Iter::value_type mean(Iter first,Iter last);

void f (vector<int>& v,int* p,int n)

{

auto x = mean(v.begin(),v.end()); //ok. has Value_type;

auto y = mean(p,p+n); //error. int has not value_type..

}

//总结;

注意:默认情况下,编译器假定依赖名字不是类型名,因此,为了使依赖性名字可以是一个

类型,你须用关键字typename显示说明。
如:
template<typename Container>
void fct(Container& c){
{
Container::value_type v1 = c[7] ; //语法错误,编译器默认假设依赖名不是类型名
typename Container::value_type v2 = c[9]; //ok.显示说明value_type是类型
auto v3 = c[11] ; //也正确,让编译器推断;

标准库STL中的Vector 的 value_type,正是为了避免这样的问题而引入了依赖性名字,从而可以引用类型别名来代替typename的尴尬:

template<typename T>
using Value_type<T> = typename T::value_type;

template<typename Container>
void fct2(Container& c){
value_type<Container> v1 = c[7] ;// 展开还是用了typename 声明;但界面友好些

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值