C++: Metaprogramming

來源:互聯網
上載者:User

今天在書店裡翻 "C++ template" 學習了一下以前一直不明白的Metaprogramming,發現原來就是那個在模板裡加enum的技巧的應用,仔細想一下果然可以衍生出很多用途,下面是一個最簡單的例子:
#include <iostream>
using namespace std;

template<int n>
class twoPower
{
public:
 enum { result = 2*twoPower<n-1>::result };

};

template<>
class twoPower<0>
{
public:
 enum {result = 1};
};

int main()
{
 cout << twoPower<5>::result <<endl;
}

定義了一個用來算2的n次方的模板,用了模板的特化來做為遞迴的終止條件。第一次接觸到這樣形式的模板應用是在"Modern C++ Design" 的typelist裡,當時就非常的驚訝,發現C++的表達能力實在是我無法想像的。

今天,書店裡思考了一會兒,覺得這個技術可以用來在編譯期實作類別似.net中attribute的東西。回來在機器上試了一下,像這樣:
首先定義一個attribute的模板類,並提供一個預設值:

template<typename T>
class SerializableAttribute
{
public:
 enum { IsSerializable = 0 };
};

然後你定義了一個自己的類,比如這樣:

class myClass
{
};

為了應用上面的那個Attribute,你需要為你的類提供一個特化:

template<>
class SerializableAttribute<myClass>
{
public:
 enum {IsSerializable = 1 };
};

然後,在其它地方就可能用到這個attribute。(reflect嗎? )

int main()
{
 if (SerializableAttribute<myClass>::IsSerializable) cout << "myClass can be serialized." <<endl;
 else cout <<"myClass can't be serialized" <<endl;
}

我想以上這種應用,應該就是這種技術被稱為metaprogramming的原因吧。這樣的Attribute和.net中的Attribute最大的大區別是它是靜態,因為模板的推導工作全部都是在編譯期完成的,而不是像.net中那樣將metadata編譯進assembly裡,然後再在執行期運用反射來擷取。這當然會使得它的用途受到諸多限制。

不過有時候我在想,像C++這樣缺乏運行時支援,到底是劣勢呢?還是優勢呢? 最近在研究C#2.0中的泛型機制,其中新提出來的 約束 的機制,我個人猜測很可能就是因為C#太強大的反射機制,導致泛型的推導,不能像C++那樣完全在編譯期完成,才不得不加上的。

C++中的編譯期多態,在C#中似乎也沒有辦法使用了。不過說不定加入泛型的C#,又會生出許多新的應用,誰知道呢! 當初為C++加入模板的時候,stroustup教授自己恐怕也沒有想到泛型會有今天的發展吧。語言總會給我們帶來驚喜,誰說不是呢。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.