metaprogramming含有“对一个程序进行编程”的意思。换句话说,编程系统将会执行我们所写的代码,来生成新的代码,而这些新代码才真正实现了我们所期望的功能。
通常而言,metaprogramming这个概念意味着一种反射的特性:metaprogramming组件只是程序的一部分,而且它也只生成一部分代码或者程序。
我们为什么需要metaprogramming呢?和大多数程序设计技术一样,使用metaprogramming的目的是为了实现更多的功能,并且使花费的开销更小,其中开销是以:代码大小、维护的开销等来衡量的。另一方面,metaprogramming的最大特点在于:某些用户自定义的计算可以在程序翻译期进行, 而这通常都能够在性能(因为在程序翻译期所进行的计算通常都可以被优化)或者接口简单性(一个metaprogram通常都要比它所扩展的程序简短)方面带来好处;甚至为两方面同时带来好处。
Metaprogram的第一个实例
在1994年C++标准委员会的一次会议上,ErwinUnruh提出了:可以使用模板来在编译期进行某些计算。于是,他写了一个用于产生素数的程序。其中特别的是:生成素数的计算是编译器在编译期执行的,而不是在运行期执行。最后,尽管这个程序并不是严格可移植的(因为错误信息没有标准化),但是该程序表明了:模板实例化机制是一种基本的递归语言机制,可以用于在编译期执行复杂的计算。因此,这种随着模板实例化所出现的编译期计算通常就被称为template metaprogramming。
下面的程序给出了如何在编译期计算3的幂:
template<int N> class Pow3 {
public:
enum {
result = 3 * Pow3<N - 1>::result
};
};
//用于结束递归的全局特化. 模板特化
template<>
class Pow3<0> {
public:
enum {
result = 1
};
};
int main() {
std::cout << "Pow3<4>::result = " << Pow3<4>::result<<std::endl;//输出81
}
实际上,在template metaprogramming后面所做的工作是递归的模板实例化。在这个计算3的N次幂的递归模板实例化将应用下面这两个规则:
1) 3^N=3*3^(N-1)
2) 3^0=1
对于第一个Pow3<>模板,当实例化一个正数N的时候,模板Pow3<>需要计算所含枚举值的结果,这个值将会是:以N-1为模板参数实例化相同模板后,对应模板的result值乘以3。
第2个模板是一个用于结束递归的特化,它确定了Pow3<0>的结果是1.
在这里,Pow3<>模板(包含它的特化)就被称为一个template metaprogramming。它描述一些可以在翻译期(编译期)进行求值的计算,而这整个求值过程属于模板实例化过程的一部分。
Other: 理解template<int N>:
c++ - What does template <unsigned int N> mean? - Stack Overflow
Ref:
《C++ Templates》17.1