模板中tempname与class区别

前言

在分析traits编程以前, 咱们须要对模板参数类型tempnameclass有必定的了解, 要明白他们在哪些方面不一样, 哪些方面相同, 这样才能对体会到traits编程的核心. 若是你已经明白了二者, 那么你能够直接看下一篇了.编程

相同之处

通常对模板参数类型typenameclass认为是同样的. 这二者在参数类型中确实是同样的. 你能够写成函数

template<class T> 
class point {};

也能够写成code

template<typename T>
class point {};

这二者都是同样的, 没有区别. 二者typenameclass参数类型中没有不一样继承

既然相同又为何定义这两个符号呢?编译器

  1. 最开始定义定义模板的方法就是template<class T> , 可是class毕竟都认为是一个类, 在使用时不免会有些点混淆, 也就定义了typename来标志参数类型
  2. 最重要关于 typename可使用嵌套依赖类型, 也就是类型能够嵌套使用. 这也是两个的不一样之处.

不一样之处

typename能够用在嵌套依赖中, 而且表示其类型, 而class并无这样的功能.it

什么是嵌套依赖? 咱们以一个简单的实例来看编译

template<class T>
class people
{
    public:
        typedef T   value_type;
        typedef T*  pointer;
        typedef T&  reference;
};

template<class T>
struct man 
{
    public:
        typedef typename T::value_type  value_type;
        typedef typename T::pointer     pointer;
        typedef typename T::reference   reference;
        void print()
        {
            cout << "man" << endl;
        }
};

int main()
{
    man<people<int>> Man;
    Man.print();

    exit(0);
}

以上就是typename的嵌套使用. typename告诉编译器这不是一个函数, 也不是一个变量而是一个类型. 这里使用typedef又将参数类型从新定义一次, 1. 增长了一层间接性, 2. 使用的时候也不须要在写很长的代码.模板

这里typename是对people类中定义的类型进行了一次提取, 这里将typename改成class就会出错.class

typename主要的做用:基础

  • 对于模板参数是类的时候, typename可以提取出该类所定义的参数类型.

并非全部的嵌套依赖类型都要加上typename, 有一个例外 : 当继承列表或成员初始化列表中对基类进行初始化的时候, 能够去掉typename关键字

man(int x) : T::value_type(x) {}

总结

这里对typename作了一个浅显的分析, 这也足够咱们能够分析traits编程的基础了. 我再将以上的分析作一个概括.

  1. typenameclass在做为参数类型时用法同样, 没有区别
  2. typename主要用于对嵌套依赖类型进行提取(萃取). 而class没有这样的功能.
  3. typename提取的一个例外是在继承或成员初始化列表中对基类进行初始化时不用加typename关键字
相关文章
相关标签/搜索