程序的运行效率是每个程序员都不得不在意的东西,把运行阶段的某些操作转移到编译期处理掉,是美丽的诱惑,我无法抵挡这种诱惑。
在这个世界中,编译阶段推导是核心,毕竟我们能做的事情不多,只能操作常量级别的推导。
1.计算长度
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 };
} ;
template <> struct Length < NullType >
... {
enum ...{value = 0;}
} ;
template < class T, class U >
struct Length < Typelist < T,U > >
... {
enum ...{value = 1 + Length<U>::value };
} ;
在这里采用了偏特化、NullType技术,注意这里模板参数和实际传给类的参数之间的联系和区别,看清区别是正确理解的关键。
2.编译期工具
template提供了编译期间的if选择能力、Integer calculations提供了数值计算能力(但这是一旦确定无法改变的,譬如enum)、typedef提供了类型常数。
3.索引式访问
template
<
class
Head,
class
Tail
>
struct TypeAt < Typelist < Head,Tail > , 0 >
... {
typedef Head Result;
} ;
template < class Head, class Tail,unsigned int i >
struct TypeAt < Typelist < Head,Tail > ,i >
... {
typedef typename TypeAt<Tail,i - 1>::Result Result;
} ;
struct TypeAt < Typelist < Head,Tail > , 0 >
... {
typedef Head Result;
} ;
template < class Head, class Tail,unsigned int i >
struct TypeAt < Typelist < Head,Tail > ,i >
... {
typedef typename TypeAt<Tail,i - 1>::Result Result;
} ;
这里也是依照模板偏特化提供的选择能力进行的递推。
4.查找typelist
template
<
class
TList,
class
T
>
struct
IndexOf;
template < class T >
struct IndexOf < NullType,T >
... {
enum ...{value = -1};
} ;
template < class Tail, class T >
struct IndexOf < Typelist < T,Tail > ,T >
... {
enum ...{value = 0 };
} ;
template < class Head, class Tail, class T >
struct IndexOf < Typelist < Head,Tail > ,T >
... {
private:
enum ...{temp = IndexOf<Tail,T>::value};
public:
enum ...{ value = temp == -1 ? -1 : 1 + temp };
} ;
template < class T >
struct IndexOf < NullType,T >
... {
enum ...{value = -1};
} ;
template < class Tail, class T >
struct IndexOf < Typelist < T,Tail > ,T >
... {
enum ...{value = 0 };
} ;
template < class Head, class Tail, class T >
struct IndexOf < Typelist < Head,Tail > ,T >
... {
private:
enum ...{temp = IndexOf<Tail,T>::value};
public:
enum ...{ value = temp == -1 ? -1 : 1 + temp };
} ;
代码贴出来就这样,你可以轻易推敲得到它的原理和使用的技术,但是,难的地方在于这个地方是如何设计出来的,想通这个你可以得到更多。
5.附加
关于附加,er,让我们在代码之前考虑一些事情,编译期间的处理的一个特点是一旦确定无法更改,对于附加而言我们除了重新定义别无它法,那处理方式也显而易见了:
Append
<
NullType,NullType
>
...
{typedef NullType Result}
;
Append < NullType,T > ... {typedef Typelist<T,NullType> Result} ;
Append < NullType,Typelist < Head,Tail > > ... {typedef Typelist<Head,Tail> Result} ;
Append < Typelist < Head,Tail > ,T > ... {typedef Typelist<Head,typename Append<Tail,T>::Result Result} ;
Append < NullType,T > ... {typedef Typelist<T,NullType> Result} ;
Append < NullType,Typelist < Head,Tail > > ... {typedef Typelist<Head,Tail> Result} ;
Append < Typelist < Head,Tail > ,T > ... {typedef Typelist<Head,typename Append<Tail,T>::Result Result} ;
代码已被我简化,注意这里定义新Typelist得重组策略。