什么是模板元编程
模板元编程:编译系统将会执行我们所写的代码,来生成新的代码,而这些新代码才真正实现了我们所期望的功能。
通常, 模板元编程这个概念意味着一种反射的特性,模板元编程组件只是程序的一部分,而且它也只生成一部分代码或者程序。
为什么要引入模板元编程
模版元编程的最大特点在于:某些用户自定义的计算可以在程序翻译期进行。而这通常都能够在性能(在程序翻译期所进行的计算通常可以被优化)或者接口简单性(一个模板元编程通常比它所扩展的程序简短)方面带来好处
看个例子
目的:使用模板在编译期间进行某些计算
模板实例化机制是一种基本的递归语言机制,可以用于在编译期执行复杂的计算。因此,这种随着模板实例化所出现的编译期计算通常被称为模板元编程。
例子:
template<int N>
class Pow3{
public:
enum {result = 3*Pow3<N-1>::result};
};
template<>
class Pow3<0>{
public:
enum {result = 1};
};
实际上,在模板元编程后面所做的工作是递归的模板实例化。在这个计算
3
N
3^N
3N的递归模板实例化将应用下面两个规则:
首先,第1个模板实现了一般的递归原则:
template<int N>
class Pow3{
public:
enum {result = 3*Pow3<N-1>::result};
};
当实例化一个正数N时,模板Pow3<>需要计算所含枚举值的结果,这个值将会是以N-1为模板参数实例化相同模板后,对应模板的result值*3;
而第2个参数是一个用于结束递归的特化,它确定了Pow3< 0 >的结果:
template<>
class Pow3<0>{
public:
enum {result = 1};
};
那怎么用呢?
int main(){
std::cout << Pow3<7>::result ;
}
在这里,Pow3< 3 >模板(包含它的特化)就被称为一个模板元编程。它描述一些可以在(翻译期)编译期进行求值的计算。而这整个求值过程属于模板实例化过程的一部分
枚举值和静态常量
在原来的C++编译器中,在类声明的内部,枚举值是声明“真常值”(也成为常量表达式)的唯一方法。然而,现在的情况已经发生了改变,C++的标准化过程引入了在类内部进行静态常量初始化的概念。例如:
struct TrueConstants{
enum {Three = 3};
static int const Four = 4;
};
也即是说,上面的Pow3可以更改如下:
template<int N>
class Pow3{
public:
static int const result = 3 * Pow3<N - 1>::result;
};
template<>
class Pow3<0>{
public:
static int const result = 1;
};
与上一个版本不同的是,这里使用静态常量成员,而不是枚举值。但是,这个版本有一个缺点:静态成员变量只能是左值。因此,推荐使用枚举值,而放弃使用静态常量