2 回答
TA贡献1804条经验 获得超8个赞
很多回答都是复制粘贴一段没有什么用处的。我来说几句,如果lz满意,希望采纳,鼓励下诚实原创的回答。如果不满意,欢迎追问。
模板元编程的意思是使用模板实现元编程,它的内涵比模版本身(java称为泛型)大得多。模版可以看作元编程最基本的运用。
所谓元编程,就是编写一个用来编程的程序(生成代码的程序),元xx(英文meta-xxx)就是xxx的xxx。比如,元学习就是学习如何学习的方法,元数据就是描述数据的数据,等等。
C++的模版之所以可以用来作为代码生成器,是因为它是图灵完备的,也就是说,它可以实现一切编程语言能实现的功能,关键的一条是,C++的模版可以定义参数变量。而不仅仅是类型。
比如
计算1+2+3...+100
我们可以不用循环,只用递归实现,那就是
给定一个n=100,我们可以让机器生成如下代码:
int sum_n_1()
{
return 100 + sum_n_2();
}
注意sum_n_2这个函数也不存在,但是我们可以继续生成这么一个函数
int sum_n_2()
{
return 99 + sum_n_3();
}
...
直到生成一个
int sum_n_100()
{
return 1;
}
那么要计算1+2+3...+100,如果机器生成了以上100个函数,我们只要调用sum_n_1()是不是就算出来了呢?
这个过程关键是这100个函数,是自动生成的,而不是我们自己一个一个写的。用C++模版得到如下代码:
#include <iostream> template<typename T, int i=1> class someComputing { public: typedef volatile T* retType; // 类型计算 enum { retValume = i + someComputing<T, i-1>::retValume }; // 数值计算,递归 static void f() { std::cout << "someComputing: i=" << i << '\n'; } }; template<typename T> // 模板特例,递归终止条件 class someComputing<T, 0> { public: enum { retValume = 0 }; }; template<typename T> class codeComputing { public: static void f() { T::f(); } // 根据类型调用函数,代码计算 }; int main(){ someComputing<int>::retType a=0; std::cout << sizeof(a) << '\n'; // 64-bit 程序指针 // VS2013 默认最大递归深度500,GCC4.8 默认最大递归深度900(-ftemplate-depth=n) std::cout << someComputing<int, 500>::retValume << '\n'; // 1+2+...+500 codeComputing<someComputing<int, 99>>::f(); std::cin.get(); return 0; }
就可以实现生成代码的功能。
因为这个过程完全是编译器做的,所以最后生成的计算1+2+3...+100
会自动展开函数,得到5050,也就是结果。
那么显然当程序运行的时候,直接就输出结果了,程序不需要再求和。求和的过程提前到编译阶段就完成了。
我们可以用解释语言来类比:
解释语言实现了运行的时候编译
元编程实现了编译的时候运行。
- 2 回答
- 0 关注
- 1354 浏览
添加回答
举报