2011-01-11 55 views
5

我一直在使用metaprogramming,但有時候c宏和模板的組合還不夠。除模板之外是否還有任何C++元編程替代方案?

我想缺點將可能是缺乏跨平臺的兼容性,如果元編程平臺是唯一的,比如說,Linux的等

所以呀,有沒有可用的這樣的事情,現在,除了模板?谷歌搜索元編程主要是模板metaprogramming,所以現在很難找到..

編輯:這是我一直在努力的一個例子。

假設我有一個通用類來保存/加載緩衝區中的文件。我們稱之爲FilePack。

我有一個定義的宏,它看起來像

defineFilePack(BaseClass, "code-a") 

它基本上創建了一個名爲「BaseClassPack」類,它被定義爲一個子類。下面是那個東西。

class FilePack{ 
    public: 
     char * thebuffer; 
     int bufsize; 
     string packcode; 

     // and constructors etc 
     FilePack(const string& thecode, int bufsize); 
     void operator=(FilePack& rhs); 
     void saveToFile(const string& filename); 
     void loadFromFile(const string& filename); 
     // .. and all the function you'd expect to see in a class like this 

}; 

// the person details 

class PersonDetails{ 
    public: 
     solidstring<64> name; 
     int age; 
     DateTime birthday; 
     // .. yada yada yada 
}; 


defineFilePack(PersonDetails, "psd") 

// the above creates the following class 

class PersonDetailsPack : public FilePack{ 
    public: 
     PersonDetailsPack(): 
     FilePack("psd", sizeof(PersonDetails)){ // etc 

     } 

     PersonDetails& get(){ 
     return *(PersonDetails*)getBuffer(); 
     } 

     // and a lot more convenience function 

}; 

現在,實際上是由FilePack的構造一個內置的檢查申報代碼尺寸相匹配,採用了全球地圖。

現在我很難理解如何使用模板元編程,它實際上非常適合它,因爲所有這些filepack代碼都是在源文件中聲明的。當然,有人可能會在運行時創建自己的FilePack,但那不是重點。

元編程可以幫助的另一件事是支持加載不同版本的FilePack。假設我必須更新PersonDetails類。我只是創建一個新類,使用某種元編程來聲明繼承,並且神奇地讓FilePack知道,以便在加載舊版本的PersonDetails時可以調用轉換函數,或者隨你。

此外,歡迎您對該架構發表評論,並且我很樂意聽到關於它的任何評論,但它可能有點偏離主題?

+0

你能提供一個模板+宏不夠的例子嗎?這將是討論的一個好的起點。 – 2011-01-11 20:14:05

+2

@David Rodriguez:例如,生成通過網絡連接序列化類的代碼,或者通常爲每個成員做些事情。 – 6502 2011-01-11 20:15:43

+0

「,但是有時候c宏和模板的組合不夠」 - 什麼是缺失/不夠? – Naveen 2011-01-11 20:15:47

回答

5

您也可以使用預處理器進行元編程。

你也可以考慮使用專用預處理器來生成代碼作爲「元編程」。然後你可以包含諸如lex/yacc和Qt MOC之類的東西。

1

我認爲這個工作對於Python來說是完美的。簡單的方法是使用自定義文件格式來描述如何創建類,然後可以生成實現和接口(即使使用多種語言)。因爲複雜的C++語法......(以及爲什麼要限制你自己想要表達的內容?),解析現有的C++頭文件反而是一場噩夢。

Python是多平臺和一個非常好的語言本身......

如下面的例子是我用的「增強」 C++的例子...

// 
// U8 -> F32 format converter 
// 
// - src(Image:U8) ............ source image 
// - dst(pImage:F32:src) ...... destination image 
// 
ImgFilter u8_to_f32(Image& src, Image& dst) 
{ 
    const double k = 1.0/255; 
    for (int y=0; y<src.h; y++) 
    { 
     unsigned char *rp = src.u8(0, y); 
     float *wp = dst.f32(0, y); 
     for (int x=0,w=src.w; x<w; x++) 
      *wp++ = *rp++ * k; 
    } 
} 

功能和名稱/參數上面的評論是由生成的.h該處理內存分配,大小和格式兼容性檢查,命令行參數解析的函數,C++代碼的Python腳本讀取在線幫助和python綁定。 基本上我只能寫「肉」,併爲我生成所有的樣板文件。這樣做的python腳本是200行,並給定了生成的代碼的數量C++樣板只是幾個過濾器已經超過了這一點。

2

在語言中,只能使用模板或宏來實現元程序。例如,Boost預處理程序庫提供的元編程功能非常強大,它實現了一些真正令人驚歎的宏功能。

但是,如果您希望獲得更多的信息,您可以使用您選擇的腳本語言進行元編程。

2

如果你定義的元編程爲編寫代碼生成的代碼,那麼你有

  • 模板。
  • 預處理器。
  • 其他預處理(通常是腳本,但有時編譯器擴展)
  • 從C++代碼生成C++源代碼,實時編譯,加載爲共享庫。
  • 可能,但這就是拉伸它,也會生成機器碼,如蹦牀存根。

我覺得最有意思的不是模板或C++預處理器,它是支持交叉編程的語言擴展,例如日誌方法調用或序列化。

我記得ParcPlace爲此做了一個工具嗎?

嗯,這提醒我不要忘記檢查一下,有時。 :-)

乾杯&心連心,

0

如果要執行的代碼隨心所欲的操控,你想有一個通用的元編程工具,如程序變換系統。這些工具接受源代碼,並使用類似編譯器的技術根據您的需求對該代碼進行任意分析/修改。

我們的 DMS Software Reengineering Toolkit就是這樣一個系統。它通過對要處理的編程語言的明確描述以及希望它在源代碼上執行的任務進行參數化。 DMS在這種通用方面是獨一無二的(Jackpot是一個純Java程序轉換系統),並且在生產C++系統上用於大規模轉換任務時具有強大的C++ Front End

對於前端,DMS可以解析源代碼以抽象語法樹,構建符號表,使用直接用C++術語編寫的模式執行模式匹配或代碼轉換,並且使用註釋和原始格式重新生成可編譯源代碼。文字(完整的數字基數等)。您的程序修改可以是您可以通過AST定義的任何計算。簡言之,從語言之外,它可以做什麼語言支持的元編程功能所不能做到的。

相關問題