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函數中的,也就是說,這個值是在編譯期就已經由編譯器算出來了的,這種情況下,運行時的計算時間就會大大減少。