在分析traits
编程以前, 咱们须要对模板参数类型tempname
和class
有必定的了解, 要明白他们在哪些方面不一样, 哪些方面相同, 这样才能对体会到traits
编程的核心. 若是你已经明白了二者, 那么你能够直接看下一篇了.编程
通常对模板参数类型typename
和class
认为是同样的. 这二者在参数类型中确实是同样的. 你能够写成函数
template<class T> class point {};
也能够写成code
template<typename T> class point {};
这二者都是同样的, 没有区别. 二者typename
和class
在参数类型中没有不一样继承
既然相同又为何定义这两个符号呢?编译器
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
编程的基础了. 我再将以上的分析作一个概括.
typename
和class
在做为参数类型时用法同样, 没有区别typename
主要用于对嵌套依赖类型进行提取(萃取). 而class
没有这样的功能.typename
提取的一个例外是在继承或成员初始化列表中对基类进行初始化时不用加typename
关键字