利用 C++ 模板機制編寫在編譯期執行的程序。模板實例化過程即為「運行」,輸出為類型/常量/代碼,最終參與正常編譯。TMP 圖靈完備,可實現任意可計算邏輯。
template <unsigned N>
struct Factorial {
enum { value = N * Factorial<N-1>::value };
};
template <>
struct Factorial<0> {
enum { value = 1 }; // 終止條件
};
int main() {
cout << Factorial<5>::value; // 輸出 120,編譯期計算完成
}
關鍵特徵:遞歸模板 + 特化終止 + enum 存儲常量(不佔用運行期內存)。
Item 47 advance 示例:迭代器分類標籤派發。若用 if (typeid(...)) 運行期判斷,iter += d 對雙向迭代器會編譯報錯(不支持 +=)。TMP 可在編譯期選擇正確實現:
template <class Iter, class Dist>
void advance(Iter& it, Dist d, random_access_iterator_tag) { it += d; }
template <class Iter, class Dist>
void advance(Iter& it, Dist d, bidirectional_iterator_tag) { while(d--) ++it; }
// traits 派發調用...
將「米」「秒」「千克」編碼為不同類型,編譯器自動驗證物理公式單位正確性(如速度 = 米/秒),錯誤單位操作直接編譯失敗。
A = B + C + D 傳統產生臨時對象。TMP 構建表達式樹,賦值時單次遍歷融合循環,消除臨時變量,提升緩存命中率。
將設計決策(如線程安全、內存分配、檢查邊界)封裝為獨立 Policy 類,模板組合生成定制實現:
template <class ThreadPolicy, class AllocPolicy>
class SmartPtr : public ThreadPolicy, public AllocPolicy { ... };
| 特性 | 運行期 C++ | 編譯期 TMP |
|---|---|---|
| 變量 | 對象/引用 | 模板參數/類型/枚舉常量 |
| 條件分支 | if/else | 模板特化 / SFINAE / enable_if |
| 循環 | for/while | 遞歸模板實例化 |
| 函數 | 函數 | 模板結構體 (metafunction) |
| 返回值 | return | 嵌套 ::type 或 ::value |
consteval/constexpr 新特性:現代編譯期計算更直觀,逐漸取代傳統 TMP。static_assert 斷言。