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

Item 48:了解模板元編程

編輯:關於C++

Item 48: Be aware of template metaprogramming.

模板元編程(Template Metaprogramming,TMP)就是利用模板來編寫那些在編譯時運行的C++程序。模板元程序(Template Metaprogram)是由C++寫成的,運行在編譯器中的程序。當程序運行結束後,它的輸出仍然會正常地編譯。

C++並不是為模板元編程設計的,但自90年代以來,模板元編程的用處逐漸地被世人所發現。

  • 模板編程提供的很多便利在面向對象編程中很難實現;
  • 程序的工作時間從運行期轉移到編譯期,可以更早發現錯誤,運行時更加高效。
  • 在設計模式上,可以基於不同的策略,自動組合而生成具體的設計模式實現。

    靜態類型檢查

    在Item 47中提到了這樣一個std::advance的實現:

    template
    void advance(IterT& iter, DistT d) {
      if (typeid(typename std::iterator_traits::iterator_category) ==
        typeid(std::random_access_iterator_tag)){
          iter += d;
      }
      ...
    }
    
    list::iterator it;
    advance(it, 10);
    

    其實上述代碼是不能編譯的,設想以下advance::iterator, int>中的這條語句:

    iter += d;
    

    list::iterator是雙向迭代器,不支持+=運算。雖然上述語句不會執行,但編譯器不知道這一點。 編譯時這條語句仍然會拋出類型錯誤。

    模板元編程

    TMP後來被證明是圖靈完全的,這意味著TMP可以用來計算任何可計算的問題。你可以聲明變量、執行循環、編寫和調用函數等等。 但它的使用風格和普通C++完全不同。

    我們來看看TMP中如何執行一個循環:

    template
    struct Factorial{
        enum{ value = n * Factorial::value };
    };
    template<>
    struct Factorial<0>{
        enum{ value = 1 };
    };
    
    int main(){
        cout<::value;
    }
    

    這是一個典型的TMP例子,其低位就像是普通編程語言中的”hello world”一樣。

    TMP的用途

    為了更好地理解TMP的重要性,我們來看看TMP能干什麼:

    1. 確保量綱正確。在科學計算中,量綱的結合要始終保持正確。比如一定要單位為”m”的變量和單位為”s”的變量相除才能得到一個速度變量(其單位為”m/s”)。 使用TMP時,編譯器可以保證這一點。因為不同的量綱在TMP中會被映射為不同的類型。
    2. 優化矩陣運算。比如矩陣連乘問題,TMP中有一項表達式模板(expression template)的技術,可以在編譯期去除臨時變量和合並循環。 可以做到更好的運行時效率。
    3. 自定義設計模式的實現。設計模式往往有多種實現方式,而一項叫基於策略設計(policy-based design)的TMP技術可以幫你創建獨立的設計策略(design choices),而這些設計策略可以以任意方式組合。生成無數的設計模式實現方式。
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved