从哪里来看,这章都是这整本书的重中之重: 介绍了模板元编程, 编译期间编程的利器。 同时实现了typelist这个整本书为之基石的类。 虽说模板元编程晦涩难懂, 但是作者以渐进的方式, typelist为例, 将之阐述的条例清楚, 只要有一定的template基础, 还是能够看明白的了。
typelist的目的: 是为了用同样的代码来泛型处理不同类型, 只需要提供一系列的类型,那么就会自动为这一系列类型生成代码。
typlist的定义: 由一系列类型组合而成的list, 为了实现编译期的递归处理, typelist采用了一种递归定义方法:如:
#define LOKI_TYPELIST_1(T1) ::Loki::Typelist<T1, ::Loki::NullType>
#define LOKI_TYPELIST_2(T1, T2) ::Loki::Typelist<T1, LOKI_TYPELIST_1(T2) >
#define LOKI_TYPELIST_3(T1, T2, T3) ::Loki::Typelist<T1, LOKI_TYPELIST_2(T2, T3) >
更大的typelist由比他小1的typelist加一个类型构成。
接下来, 介绍了各种typelist的操作, 作者由简入深, 通过介绍这些操作, 将模板元编程的奥妙展现无遗。
1. 计算长度. 这是一个递归运算, 第一个特化, 意思是当递归到起点, 没有类型的时候, 此时:TList为NullType. 长度=0.第二个特化就是递归定义, 当长度不等于0的时候, 长度= 1 + 去掉头的typelist的长度。 相当于我们程序实现了一个递归。 区别只是: 这里利用了编译期间的模板实现来进行递归。
template <class TList> struct Length;
template <> struct Length<NullType>
{
enum { value = 0 };
};
template <class T, class U>
struct Length< Typelist<T, U> >
{
enum { value = 1 + Length<U>::value };
};
从这里可以看出编译期实现的一些特性:
1. Template, 模板提供了编译期的分支语句, 即通过不同的类型或者值(值经过intToType包装,相当于不同的类型), 生成不同的特化版本。相当于实现了不同类型之间的差异性。
2. 数值计算: 编译期间只能使用常量, 所以任何辅助的值都是常量。
3. typedefs , 可以用作定义类型常量, 当然,这个类型定义之后就不能改变了。
由于编译期间没有任何的变量可以使用, 所以只能用递归实现行为了。
2. 索引访问 提供了根据索引得到typelist中的对应类型. 递归方式类似length.
template <class TList, unsig