template metaprogramming(TMP,模版超編程)是一個有趣的技術,利用C++的template功能,產生編譯時期執行的程式,這並不是當初設計C++ template功能的本意,但自從TMP於1990s被發現以後,日漸被證明十分有用,TMP已經被證明是圖林完全(Turing-complete),意思是其威力大到足以計算任何事物。什麼是「編譯時期執行」?認識TMP的入門程式是計算N的階乘,如同程式語言書籍的第一個入門程式"Hello world"一般。在C++中我們可以利用遞迴來設計出可以計算階乘的函數:
#include <iostream>
using namespace std;
int factorial(int n) {
if (n == 0)
return 1;
return n * factorial(n - 1);
}
void main(void)
{
cout<<"10!="<<factorial(10)<<endl;
} |
利用TMP可以寫成:
#include <iostream>
using namespace std;
template<unsigned n>
struct Factorial{
enum { value =n*Factorial<n-1>::value};
};
struct Factorial<0>{
enum{value=1};
};
void main (void){
cout<<"10!="<<Factorial<10>::value<< endl;
} |
跟上一個程式不同的是,它是在編譯時期執行,這是一個非常有趣的技巧。上一個程式利用遞迴技巧來達成,在執行階段需要付出額外的堆疊空間,而TMP卻沒有這項困擾,而且由於TMP執行於C++編譯時期,使得某些錯誤原本要在執行時期才能發現,現在可以在編譯階段就被發現 ( 例如使用上面兩的程式計算30!,使用TMP在編譯時就會提出warning C4307: '*' : integral constant overflow )。但是不是每個人都喜歡TMP,因為它的語法不夠friendly,TMP是不久前才被意外發現的技巧,相關的技術文資料與工具還不夠完備,不過能夠將工作從執行時期轉移到編譯時期所帶來的效率改善是十分吸引人的,也許未來可能會被加入C++語言與標準程式庫之中。
目前有一個針對TMP設計的程式庫 - Boost MPL,Boost是一個C++開發者集結的社群,也是一個可以自由下載的C++程式庫群,網址是 http://boost.org,Boost 內含許多程式庫,Boost有一套十分嚴格審查機制,可以確保程式庫的品質,MPL便是其中知一。
參考資料:
[ 1 ] 維基百科:http://wiki.hkgamedev.org/index.php/%E6%A8%A1%E7%89%88%E5%85%83%E7%B7%A8%E7%A8%8B
[ 2 ] AK's weblog:http://www.flipcode.org/cgi-bin/fcarticles.cgi?show=63820
[ 3 ] 《Effective C++ 3/e》條款48、條款55