首页 > 代码库 > C++模板学习之递归

C++模板学习之递归

 

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函数中的,也就是说,这个值是在编译期就已经由编译器算出来了的,这种情况下,运行时的计算时间就会大大减少。

技术分享

 

C++模板学习之递归