程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 初識c++模板元編程

初識c++模板元編程

編輯:C++入門知識

模板元編程(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程序可以包含以下幾部分:

  • 狀態變量:即模板參數
  • 迭代構造: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++》

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved