元编程(Metaprogramming)是指某类计算机程序的编写,这类计算机程序编写或者操纵其他程序(或者自身)作为它们的数据,或者在编译时完成部分本应在运行时完成的工作。很多情况下比手工编写全部代码相比工作效率更高。编写元程序的语言称之为元语言,被操作的语言称之为目标语言。一门语言同时也是自身的元语言的能力称之为反射。
百度百科里元编程例子:
int Result;
//主模板
template<int N> //模板
class Fibonacci
{
public:
enum{Result = Fibonacci<N-1>::Result + Fibonacci<N-2>::Result };
//枚举,带有隐含计算
};
//完全特化模板
template<>
class Fibonacci<1> //带常参数1的构造函数
{
public:
enum { Result = 1 };
//给枚举赋初值1
};
//完全特化模板
template<>
class Fibonacci<0> //带参数0的模板
{
public:
enum { Result = 0 };
//给枚举赋初值0
};
int main()
{
std::cout << "第20项的Fibonacci数是:" << Fibonacci<20>::Result << std::endl;
//隐含计算
system("pause");
return 1;
}
定义了一个类模板,类中声明了一个枚举类型,该程序的奥秘就在枚举类型的构造上。从枚举类型的构造可以看出,他自身有一个样俺的迭代计算。两个构造函数为枚举类型初始化了数列的初始值,当调用“Fibonacci<20>::Reasult“时,就以这两个初始值为基础进行迭代。因此,程序在运行时并没有显示的计算,而是在编译时就由编译器计算了。
当编译器实例化Fibonacci<20>时,为了给其enum Result赋值,编译器需要对Fibonacci<19>和Fibonacci<18>进行实例化,之后同理······,当实例化到Fibonacci<1>和Fibonacci<0>的时候,完全特化模板被实例化,至此迭代结束。
接下来,编写了一下的代码,测试元编程,模板,函数三种方式实现数组求和的效率如下:
#include "time.h"
/*http://blog.youkuaiyun.com/sunboyiris?viewmode=list*/
template <typename T>
inline T sum_array(int Dim, T* a)
{
T result = T();
for (int i = 0; i < Dim; ++i)
{
result += a[i];
}
return result;
}
template <int Dim, typename T>
class Sumarray
{
public:
static T result(T* a)
{
return a[0] + Sumarray<Dim-1, T>::result(a+1);
}
};
// 作为终结准则的模板
template <typename T>
class Sumarray<1, T>
{
public:
static T result(T* a)
{
return a[0];
}
};
//模板实现数组内各元素相加
template<T array>
void arraysun(T &v,int sz)
{
float k=0;
for (int i = 0; i < sz; ++i)
{
k+=v[i];
}
cout<<k<<endl;
}
int main()
{
float k=0;
srand(time(NULL));
clock_t ibegin, iend;
int a[3000];
for(int i=0;i<3000;i++)
{
a[i]=i;
}
//模板实现测试
ibegin = clock();
arraysun(a,3000);
iend = clock();
cout<<endl;
cout<<"耗时"<<endl;
cout<<iend-ibegin<<endl;
//常规函数测试
ibegin = clock();
for(int i=0;i<3000;i++)
{
k+=a[i];
}
cout <<" "<< k;
iend = clock();
cout<<endl;
cout<<"耗时"<<endl;
cout<<iend-ibegin<<endl;
//元编程测试
ibegin = clock();
cout <<" "<< Sumarray<3000, int>::result(a);
iend = clock();
cout<<endl;
cout<<"耗时"<<endl;
cout<<iend-ibegin<<endl;
system("pause");
return 0;
}