14

究竟是什麼區別?好像條款可以稍微交替使用,但閱讀的Objective-C的維基百科條目,我碰到:泛型編程v.s. Metaprogramming

除了程序 編程的C'S風格,C++直接支持 的對象 - 某些形式面向對象的編程,泛型編程和編程 。

參照C++。顯然他們不一樣?

+0

Offtop語言問題:v.s.還是vs.? - 「v.s.」與「對比」 :) – 2010-10-14 21:25:25

+2

@阿門:這也帶來了一個問題:「v.s. vs. vs.」與「v.s. v.s.與」比較? – Claudiu 2010-10-14 21:36:26

+3

@Claudiu:讓神聖的遞歸遞歸! :D – 2010-10-14 21:37:31

回答

12

從廣義上講,元編程意味着編寫產生其他程序的程序。例如。像C++中的模板只在實例化時才生成實際的代碼。人們可以將模板解釋爲一種將類型作爲輸入並生成實際功能/類作爲輸出的程序。預處理器是另一種元編程。另一個構成元編程的例子:一個讀取XML並根據XML生成一些SQL腳本的程序。再說一次,元程序是產生另一個程序的程序,而泛型編程則是關於參數化(通常是其他類型)類型(包括函數)的程序。

考慮的評論這個答案後可進行編輯

+1

是的,您可以將模板視爲元程序,但您不能真正做到與例如java泛型。所以我會說:使用元編程可以實現泛型編程,但這不是唯一的方法。 – sepp2k 2010-10-14 21:13:47

+1

@ sepp2k:嗯,我在C++中指定了模板。但我同意在其他語言中泛型編程不一定涉及元編程 – 2010-10-14 21:17:51

+0

@ sepp2k:這是一個很好的觀點,我只在我的回答中暗示。 IMO比Java泛型更好的例子(涉及編譯器在類型擦除中的至少一些合作)是Common Lisp中的通用函數,其中調度純粹通過檢查運行時類型來完成(IIRC,我不是Lisp專家,所以糾正我,如果我錯了)。 – 2010-10-14 21:32:32

4

泛型編程通常指的是可以處理多種類型的函數。例如。一個排序函數,它可以對一個可比較對象集合進行排序,而不是對一個排序函數進行排序,對一個整數數組進行排序,對另一個排序函數進行排序。

元編程是指以編程方式檢查,修改或創建類,模塊或函數。

7

我會大致定義爲元編程「編寫程序編寫程序」和泛型編程爲「使用的語言功能編寫函數,類等的數據類型參數的論據或成員「。通過這個標準,C++模板對於泛型編程(例如vectorlistsort ...)和元編程(認爲Boost和例如Spirit)都是有用的。此外,我認爲用C++進行泛型編程(即編譯時多態)是通過元編程(即從模板代碼生成代碼)來完成的。

4

最好看看其他語言,因爲在C++中,單一特性支持泛型編程和元編程。 (模板非常強大)。

在Scheme/Lisp中,您可以更改代碼的語法。人們可能知道Scheme是「帶有許多括號的前綴語言」,但它也具有非常強大的元編程技術(Hygenic Macros)。特別是,try/catch可以是創建的,甚至可以將語法操縱到某一點(例如,如果您不想再寫前綴代碼,則這裏是插入轉換器的前綴:http://github.com/marcomaggi/nausicaa)。這是通過元編程完成的,編寫寫代碼的代碼。這對於嘗試新的編程範例非常有用(AMB操作員在非確定性編程中扮演着重要角色,我希望AMB將在未來5年左右成爲主流......)

在Java/C#中,你可以通過泛型進行泛型編程。您可以編寫一個支持許多其他類的類型的泛型類。例如,在Java中,您可以使用Vector創建一個整數向量。如果你想要特定於你自己的班級,可以使用Vector。

在事情變得奇怪的地方,C++模板是爲通用編程設計的。但是,由於一些技巧,C++模板本身就是完整的。使用這些技巧,可以通過元編程爲C++語言添加新功能。它的複雜,但它的作品。以下是通過模板向C++添加多個派發的示例。 http://www.eptacom.net/pubblicazioni/pub_eng/mdisp.html。較典型的例子是斐波那契在編譯時:http://blog.emptycrate.com/node/271

32
  • 編程:編寫用於創建,轉換,過濾器,聚集體和否則操縱數據的程序。
  • 元編程:編寫程序創建,轉換,過濾,聚合或以其他方式操作程序
  • 通用編程:編寫一個創建,轉換,過濾,聚集或以其他方式處理數據的程序,但只對數據結構做出最小假設,從而最大限度地重用各種數據類型。

正如已經在其他幾個答案中提到,這種區分可以在C++混淆,因爲兩者泛型編程和(靜態/編譯時間),元編程與模板完成。爲了進一步混淆你,C++中的泛型編程實際上使用了Metaprogramming來提高效率,即模板專門化從通用編程中生成專用(快速)程序。另外請注意,每個Lisp程序員都知道,代碼和數據是相同的東西,所以實際上沒有「元編程」這樣的東西,它只是編程而已。再一次,在C++中很難看到,因爲實際上使用了兩種完全不同的編程語言來編程(C++,C系列中的一種命令式,過程式,面向對象的語言)和元編程(模板,一種純粹功能性的「意外「語言介於純演算和Haskell,與對接醜陋的語法之間,因爲它從來沒有真正打算一種編程語言。)

許多其他語言使用的編程和元編程相同的語言(例如, Lisp,模板Haskell,Converge,Smalltalk,Newspeak,Ruby,Ioke,Seph)。

0

泛型編程是一種非常簡單的元編碼形式,儘管通常不是運行時。它更像C中的預處理器,在大多數用例和基本實現中更多地涉及模板編程。

你會經常在類型化語言中發現,你將創建一些只有類型不同的實現。在像Java這樣的語言中,這可能會特別痛苦,因爲每個類和接口都定義了一種新類型。

您可以通過將它們轉換爲字符串文字來生成這些類,然後用變量替換類名以進行插值。

其中泛型在運行時使用有點不同,在這種情況下,它只是可變編程,使用變量編程。

設想的方式很簡單,就是採取文件,比較它們並將不同的東西變成變量。現在你只有一個可重用的文件。您只需指定不同的內容,即名稱變量。

泛型是如何產生的,並非所有東西都可以像您期望的變量類型或鑄造類型那樣變化。通常會有很多文件重複,其中唯一可變的是變量類型。這是一個非常常見的重複來源。雖然有辦法解決這個問題,但並不是特別方便。泛型已經成爲一種變量變量來允許變量類型變量。因爲變量類型通常是在編程語言中表達的東西,現在可以在運行時指定它,所以它也被認爲是元編碼,儘管這是一個非常簡單的情況。

沒有變化,你需要它來展開你的變量的影響,這就是你被迫,而不是具有可變作出實施每一個可能是變量的值。

正如你可以想象,這是相當昂貴的。使用任何類型的重用對象存儲庫時,這將非常常見。這些將接受任何對象,但在大多數情況下,人們只想痛苦一種類型的objdct。如果您放入一個擴展Object的Shop對象然後想要檢索它,存儲對象上的方法簽名將僅返回Object,但您的代碼將期望Shop對象。除非您將它重新投入購物,否則這將會破壞對象降級的編譯。這引發了另一個難題,因爲沒有泛型,沒有辦法檢查兼容性,並確保您存儲的對象是Shop類。

Java避免了元編程,並嘗試使用面向對象的多態性原則來簡化語言,而不是製作靈活的代碼。然而,通過經驗呈現並且通過添加最少的元編程設施來解決一些緊迫和重複出現的問題。 Java不想成爲一門元程序語言,但很少從這裏引入概念來解決最棘手的問題。

提供灌洗元代碼設施的編程語言可以比語言更有效率,比避免禁止特殊情況,反射,OOP多態等。然而,它常常需要更多的技巧和專業知識來產生不可理解的,可維護的和無錯代碼。對於這樣的語言,C++經常會有性能損失,因爲它被編譯爲本地語言。