metaprogram含有对一个程序进行编程的意思,换句话说,编程系统将会执行我们所写的代码,来生成新的代码,而这些新的代码才真正实现了我们所期望的功能,通常而言,metaprogram 这个概念意味着一种反射的特性,metaprogram组件只是程序的一部分,而且它只生成一部分代码或者程序。
我们为什么需要metaprogram 呢?和大多数程序设计一样,使用metaprogram的目的是为了实现更多的功能,并且使话费的开销更小,其中开销是以,代码大小,维护的开销等来衡量的,另一方面。metaprogram 的最大特点在于,某些用户自定义的计算可以在程序翻译期间志兴,而这通常能够在性能或者接口简单方面带来好处,甚至为两方面同时带来好处。
metaprogram 要依赖于我们在第15章所介绍的关于trait 和类型函数的概念。
1 metaprogram的第一个实例
在1994年C++标准一次会议上,Erwin Unruh提出了,可以使用模版来编译期进行一些计算,于是,他写了一个用于产生素数的程序,其中特别的是,生成素数的计算是编译器在编译期执行的,而不是在运行期执行的,而且对于从2到某个可配置的值,编译器都会产生一个错误信息,最后,尽管这个程序并不是严格的可移植的,但是该程序表明了,模版实例化机制是一种基本的递归语言机制,可以用于在编译器执行复杂的计算。
在深入了解metaprogram细节之前,看一个简单的例子。
#ifndef POW3_HPP
#define POW3_HPP
//用于计算3的N次方的基本模版
template<int N>
Class Pow3 {
Public:
enum {result = 3 * Pow3<N-1>::result};
}
//用于结束递归的全局特化
template<>
Class Pow3<0> {
public:
enum {result = 1};
};
#endif
实际上,在template metaprogram后面所做的工作是递归的模版实例化,在这个计算3^N的递归模版实例化应用下面的这两个规则
3^N = 3 * 3 ^N -1
2 3^0 = 1
#pragma once
template<int N>
class Pow3
{
public:
enum {result = 3*Pow3<N-1>::result};
};
//
template<>
class Pow3<0> {
public:
enum {result = 1};
};
Pow3<7>::result = 2187
root@bms-capitaland-g6v2-app-10-131-121-78:/data/demos#
root@bms-capitaland-g6v2-app-10-131-121-78:/data/demos#
root@bms-capitaland-g6v2-app-10-131-121-78:/data/demos# cat mee.cc
#include <iostream>
#include "meta.hpp"
int main()
{
std::cout<<"Pow3<7>::result = " << Pow3<7>::result << '\n';
}