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