C++中模板的推导是在编译期由编译器完成的,因此,可以利用模板将一些预先知道递归次数的递归算法用模板编程实现,以此实现将计算从运行期提前到编译期。利用模板完成递归算法与通常模式的递归算法一样,需要递归的公式和递归的结束条件。在模板元编程中,递归的公式利用模板参数的嵌套依赖来实现,而递归的结束条件利用特化模板参数来实现。比如求1到n的和,递归的公式为sum(n) = sum(n-1) + n,而递归的结束条件为sum(0)=0.于是,我们就可以写出如下的模板:
#include <iostream> template <int N> class Sum { public: enum {sum = Sum<N-1>::sum + N}; }; template <> class Sum<0> { public: enum {sum = 0}; }; int main() { std::cout << "sum of 1 to 100 is: " << Sum<100>::sum << std::endl; return 0; }
可以看到,第一个类定义template <int N> class Sum就是定义了一个主模板类,用于递归公式的计算,而第二个模板类template<> class Sum<0>是一个特化的模板类,指明在N=0时模板类的行为。需要注意的是,特化模板类的定义必须在主模板类的后面。(如果类Sum<N>未定义,编译器又怎么会知道sum<0>是个什么东西呢?)
还有一点要注意的是,此处模板类中的成员sum我们使用了枚举类型,这是因为如果使用变量的话,它是不会去在编译期推导值的(C++类成员变量初始化不能放在类定义中),当然,使用static变量也是可以的。编译运行结果:
查看编译后的程序二进制代码可以发现,5050(二进制13BA)是直接以常数的形式编到main函数中的,也就是说,这个值是在编译期就已经由编译器算出来了的,这种情况下,运行时的计算时间就会大大减少。
时间: 2024-10-19 21:42:04