[C++]template metaprogramming簡單介紹

posted in: C/C++程式設計 | 0

 

簡單來說,這玩意就是在編譯期做原本運行期在做的事情,你完全可以不需要用到這個技巧而達到同樣的功能。 例如原本運行期的OO繼承是這樣寫:

class Base{ public: virtual void someMethod() = 0; };

class Derived : public Base{ public: virtual void someMethod() override{}; };

在運行期呼叫裡面的someMethod()的時候需要再去找v-table才有辦法定位置該方法。由於所有事情都在運行時期發生,所以會有一些cost存在(方法定位的時間以及儲存v-table的空間)。只要該類別任何一個方法宣告virtual就會建立出v-table。

 

而用template寫就變成:

template <class Derived> class Base{

void someMethod(){

static_cast<Derived*>(this)->someMethodImplement();

};

};

class Derived : Base<Derived>{

public:

void someMethodImplement(){};

};

上面這個方法是template metaprogramming的一種應用,全名叫CRTP(curiously recurring template pattern)

我們可以看到template的寫法把把v-table省略掉了,尋找Derived的動作被移到編譯期上執行,因此在運行期會省一些時間。只是缺點在於寫不好的話會造成code size膨脹到非常大,而且編譯速度也會變慢。

為什麼呢?這是因為編譯器會在編譯期幫你把code產生出來,自動產生的code越多,當然code size會越大,而且編譯也會變慢。 你能想像你編譯出來的exe或lib檔大小原本只需要幾KB,但卻膨脹到MB甚至幾GB嗎?

好啦,這裡的比喻可能有點誇張,但系統一大起來的話也不是沒有可能。所以寫這個要特別注意code bloat的問題。 其實template metaprogramming在標準庫裡面用的到處都是,要能夠駕馭這套工具其實不是很容易,而且學習門檻還蠻高的。

我自己也還在學習路上 : )

好處是學會這套的話,在設計高效率的系統上會很有幫助。

Leave a Reply

Your email address will not be published. Required fields are marked *