函數(shù)式語言依賴模式匹配和遞歸完成類似命令式語言里分支選擇和循環(huán)迭代的功能。模板元編程中可以完成模式匹配的兩種方式上節(jié)已經(jīng)介紹。本節(jié)介紹模板元編程中的遞歸。
前面在介紹編譯期數(shù)值計算的整數(shù)階乘的例子時,就已經(jīng)展示了使用類模板進(jìn)行遞歸計算的一般做法。這里再補(bǔ)充一點(diǎn)就是C++11支持了變長模板參數(shù),而模板的變長參數(shù)也必須是要通過遞歸進(jìn)行參數(shù)展開的。
如下,我們實(shí)現(xiàn)一個可以對任意個IntType進(jìn)行求和的元函數(shù)Sum:
// "tlp/int/algo/Sum.h"
template<typename ...Numbers> struct Sum;
template<typename Number, typename ...LeftNumbers>
struct Sum<Number, LeftNumbers...>
{
using Result = typename Add<Number, typename Sum<LeftNumbers...>::Result>::Result;
};
template<> struct Sum<>
{
using Result = IntType<0>;
};
#define __sum(...) typename Sum<__VA_ARGS__>::Result
在上面代碼中,元函數(shù)Sum的原型是template<typename ...Numbers> struct Sum,它的參數(shù)是變長的typename ...Numbers。如果參數(shù)個數(shù)為0,則選擇特化版本template<> struct Sum<>,這時結(jié)果為IntType<0>;否則遞歸展開參數(shù),用當(dāng)前參數(shù)和剩余參數(shù)的總和進(jìn)行相加using Result = typename Add<Number, typename Sum<LeftNumbers...>::Result>::Result。注意聲明變長參數(shù)時...在參數(shù)名前面,而對其使用時...在參數(shù)名后面。
該元函數(shù)的使用如下:
__sum(); // 返回 IntType<0>
__sum(__int(1), __int(2), __int(5)); // 返回 IntType<8>