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++经常会有性能损失,因为它被编译为本地语言。