模板元編程(Template metaprogramming,簡稱TMP)是編譯器內執行的程序,編譯器讀入template,編譯輸出的結果再與其他源碼一起經過普通編譯過程生成目標文件。通俗來說,普通運行程序是編譯器生成的機器碼,由處理器解釋執行得到結果,TMP則是編譯器實例化template過程中得到結果。TMP已被證明是圖靈完備的機器,不過模板實例化通常需要消耗巨大的編譯器資源,而且難以追蹤錯誤,沒有合適的調試器,所以在實際開發中很少使用。
TMP有兩個重要的作用:
下面讓我們來看一個利用TMP計算3的冪的例子
template< N> {result=*Pow3<N-><> Pow3<> {result=<<<<Pow3<>::result<<
Pow<7>的實例化導致Pow3<6>的實例化,Pow3<6>又出發Pow3<5>的實例化,遞歸直至Pow3<0>結束,Pow<7>::result直接被常量值替換。
一個TMP程序可以包含以下幾部分:
c++中,在類內部聲明常量值只有枚舉和靜態常量初始化兩種方式。上面的例子中可以將枚舉改成靜態常量,
template< N> result=*Pow3<N-><> Pow3<> result=
不過靜態常量是左值,如果將結果作為引用參數傳遞給一個函數,
void foo(int const&);
foo(Pow3<7>::result);
編譯器必須獲取 Pow3<7>::result的地址,這會強制編譯器實例化靜態成員的定義,並分配內存,這就跳出了編譯期范圍。
而枚舉不是左值,沒有這個約束,通過引用傳遞的時候跟使用常量值形式是一樣的,所以一般都用枚舉類型。
Reference:
《c++ templates: the complete guide》
《effective c++》