1. 簡介
自從 C++ 編譯器加入 template 泛型功能後,就替傳統的 C++ 語言帶入新的革命。C++ 語言不僅是 C 包含物件導向功能,更增加了型態通用。後來的 C++ 編譯器 為了 執行時期的效率,在template 泛型內限定計算變數型態。如此更增加編譯時期的判斷及執行時期效率。
相關的簡介可參考以下網站:
https://riptutorial.com/cplusplus/topic/462/metaprogramming
2. 練習:將 Fibonacci 數列改寫成 meta programming
傳統的 C 語言寫出Fibonacci 數列
long fib(int n)
{
if((n == 0) || (n == 1))
return 1;
else
return fib(n-1) + fib(n-2) ;
}
利用 template 改寫成:
template<T>
long fib(T n)
{
if((n == 0) || (n == 1))
return 1;
else
return fib(n-1) + fib(n-2) ;
}
利用 meta programming 在 compiling time
就
template<long N>
struct Fib
{
enum{ value = Fib <N - 2>::value + Fib <N - 1>::value }; //
};
template<>
struct Fib<1>
{
enum { value = 1 };
};
然後在 main() 呼叫
cout << "Fib<5>::value = " << Fib<7>::value << endl;
經過編譯,出錯了

編譯器說內容太複雜,到網路上找資料
說是 終止條件沒給

但是上面都給了終止條件。仔細思考一下,
Fib(n-1)+Fib(n-2)
Fib(1) 有,Fib(0) 卻沒有
再加上 Fib(0)
template<>
struct Fib<0>
{
enum { value = 1 };
};
呼叫時採用 Fib<7>::value
這樣就通過編譯了,也順利執行

3. C++ 2011
#include <type_traits>
#include <iostream>
template<long long n>
struct Fib_c11 :
std::integral_constant<long long, (Fib_c11 <n - 1>::value) + (Fib_c11 <n - 2>::value) > {};
template<>
struct Fib_c11<0> :
std::integral_constant<long long, 1> {};
template<>
struct Fib_c11<1> :
std::integral_constant<long long, 1> {};
4. C++ 2014 版
新加入 constexpr 關鍵字
constexpr long long Fib_c14(long long n)
{
if (n == 0 || n == 1)
return 1;
else
return Fib_c14(n - 1) + Fib_c14(n - 2);
}
呼叫時採用 Fib_c14(7) 不需要 ::value
