之前使用模板時,只記得有typename,class做參數的。當再看到時,才感覺還是挺神奇。
模板參數並不局限於類型,可以使用編譯器內建類型。
template告訴編譯器,雖有的定義中將包含一個或多個未確定的量(常量或類型),當該模板產生實際代碼時,必須制定這些量由編譯器來替換。
TMP 的 "hello world" 程式在編譯期間計算一個階乘。它不是一個很令人興奮的程式,不過,即使不是 "hello world",也有助於語言入門。TMP 階乘計算示範了通過 recursive template instantiation(遞迴模板執行個體化)實現迴圈。它也示範了在 TMP 中建立和使用變數的一種方法。看:
template<unsigned n> // general case: the value of
struct Factorial // Factorial<n> is n times the value
{ // of Factorial<n-1>
enum { value = n * Factorial<n-1>::value };
};
template<> // special case: the value of
struct Factorial<0> { // Factorial<0> is 1
enum { value = 1 };
};
給出這個 template metaprogram(模板元程式)(實際上只是單獨的 template metafunction(模板元函數)Factorial),你可以通過引用 Factorial<n>::value 得到 factorial(n) 的值。
代碼的迴圈部分出現在 template instantiation(模板執行個體化)Factorial<n> 引用了 template instantiation(模板執行個體化)Factorial<n-1> ,這樣子它便會不斷執行個體出新的類型Factorial<n-1>,並取得各個類型中value值來相乘,由於是enum常量,所以每個value的值都會在編譯時間計算出來。
所有正確的 recursion(遞迴)都會有一個出口。這裡,它就是 template specialization(模板特化)Factorial<0>。
Factorial template 的每一個 instantiation(執行個體)都是一個 struct,而每一個 struct 都會有相應的階乘值值value。