C++中typename用法

typename用法:

1、在c++模板中,用于类型参数化的关键字
2、内嵌、依赖类型名
注:C++11中, typename用于指明紧跟其后的是个类型

1. 在C++中typename一般用来声明模板的模板参数(template parameter):
   template<typename T> class X;   //T是一个模板参数
   
2.c++内嵌、依赖、类型名

为什么使用typename关键字
那么问题来了,为什么要加上typename关键字?

typedef std::vector<T>::size_type size_type;//why not?
实际上,模板类型在实例化之前,编译器并不知道vector<T>::size_type是什么东西,事实上一共有三种可能:

静态数据成员 
静态成员函数 
嵌套类型

那么此时typename的作用就在此时体现出来了——定义就不再模棱两可。

首先是两个概念:
   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 指出下面紧跟着的名称是一个类型

1、内嵌是指定义在类名的定义中的。

2、依赖是指依赖于一个模板参数。typename iterator_traits<_InputIter>::difference_type中difference_type依赖于模板参数_InputIter。

3、类型名是指这里最终要指出的是个类型名,而不是变量。
例如iterator_traits<_InputIter>::difference_type完全有可能是类iterator_traits<_InputIter>类里的一个static对象。而且当我们这样写的时候,C++默认就是解释为一个变量的。所以,为了和变量区分,必须使用typename告诉编译器。

总结:T::iterator这种名称,由于iterator具体是类型还是成员变量取决于T的类型实现,所以当我们
     知道T::iterator是个类型名称时,如果我们要使用这个类型名,前面必须要加typename.

typename紧跟类型的例子:

#include <iostream>
using namespace std;

struct MyClass {
    typedef int SubType;
};

template<typename T>
class MyTemp {
public:
    typename T::SubType* ptr;
   
    MyTemp(const decltype(ptr) a) {
        ptr = a;
    }
    
    void print() {
        cout << "ptr_value: " << *ptr << endl;
    }
    
};

int main(void) {
    int a = 10;
    MyTemp<MyClass> temp(&a);
    temp.print();
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Star星屹程序设计

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值