对我来说,设计模式是有意义的,我已经能够实际地应用它们了。
但是,当谈到现代C++类型的"generic programming /meta programming"时,我感到困惑。
--它是一种新的编程/设计范式吗?
--是否仅限于“库开发”?如果不是,什么设计/编码情况需要使用元编程/泛型编程。
--使用模板是否意味着我在做泛型编程?
我已经在谷歌上搜索了很多关于这个话题的信息,但并没有完全掌握大局。另请参阅此post。
在阅读了下面的讨论后,到目前为止,我确信(可能仍然不正确):
a)泛型编程和元编程是两个不同的概念。
发布于 2009-06-11 10:49:33
元编程是一个非常奇特的话题。了解它很有趣,它是一个强大的工具,有时您可能会发现它很有用。但它永远不会是你工具箱中最常用的工具。有时,您可能希望代码作用于一系列具有不同属性的无关类型,这就是元编程的用武之地。使用一些技巧,您可以编写一个重载的函数,只有当参数类型是整型的,或者如果它是一个指针,或者如果它是X,Y或Z类型(可能忽略Z的常量)。
它本质上是使用类型进行编程。通常,你的程序可以做一些事情,比如取两个数字并产生第三个数字,或者告诉你一个数字是否满足某些要求。元编程可以接受两个类型并生成第三个类型,或者告诉您一个类型是否满足某些要求。是的,它可能在库开发中最有用。但话又说回来,大多数代码都可以被认为是库代码。您可以说main()函数之外的所有内容都是库代码。
通常,如果您想通过元编程来解决问题,您可能希望使用相关的boost库来完成繁重的工作。当然,Boost.TypeTraits和Boost.Mpl确实可以为您简化工作。但这不是你需要知道的,也不是你经常需要的。
泛型编程是相关的(在某些情况下,可能会在幕后使用元编程来变得真正的泛型,例如,标准库使用元编程将原始指针转换为有效的迭代器,这是“迭代器”概念成为泛型所必需的),但并非完全相同。而且它得到了更广泛的应用。
每次实例化std::vector时,都会使用泛型编程。每次使用一对迭代器来处理一系列值时,都会使用泛型编程。泛型编程就是这样一种想法,即你的代码应该尽可能的泛型,并且无论放入什么类型的代码都应该工作。vector不需要包含的类型来实现"ICanBeContained“接口(还记得Java是如何要求所有东西都从Object派生出来才能存储在容器类中的吗?这意味着原始类型被装箱,我们失去了类型安全性。这不是通用的,这是一个毫无意义的限制。)
使用迭代器遍历序列的代码是通用的,可以使用任何类型的迭代器,甚至可以使用普通指针。
泛型编程非常有用,并且通常可以在很大程度上取代OOP。(请参见上面的示例。如果我可以避免这种限制,为什么我要编写一个需要包含的类型来实现接口的容器?)
通常,当您在OOP中使用接口时,不允许在运行时更改类型(当然,这种情况也时有发生),而是允许您在编译时交换另一个类型(可能在测试期间注入模拟对象,而不是使用完整的实现),或者只是解耦两个类。泛型编程可以做到这一点,而不需要您做乏味的定义和维护接口的工作。在这些情况下,泛型编程意味着您必须编写和维护更少的代码,并且可以获得更好的性能和更好的类型安全性。所以,是的,你绝对应该熟悉泛型编程。C++不是一种很好的OOP语言。如果您想严格使用OOP,您应该切换到Java或另一种更多OOP固定的语言。C++允许您编写OO代码,但它通常不是最好的解决方案。这就是为什么几乎整个标准库都依赖于泛型编程而不是OOP的原因。标准库中几乎没有继承或多态性。他们不需要它,没有它,代码变得更容易使用和更强大。
为了回答你的其他问题,是的,泛型编程几乎是一个独立的范例。模板元编程不是。它是操纵类型系统的一种相当特殊的技术,并且非常擅长解决少数问题。要被认为是一个范例,我认为它必须是更普遍的有用的,你可以使用的方法,基本上所有的东西,像函数式,面向对象或泛型编程。
我认为xtofl确实做到了这一点:泛型编程就是让你的代码不知道类型。( std::vector不关心,也不需要知道它存储的是什么类型。它就能正常工作。)
另一方面,元编程是关于类型计算的。给定类型T0和T1,我们可以定义一个类型T2,就像我们可以定义一个整数N0和N1一样,我们可以定义一个N2,它是N0和N1的和。
Boost.Mpl库有一个很明显的例子。在普通代码中,如果有整数N0、N1和N2,则可以创建包含这三个值的std::vector。然后,我可以使用其他算法来计算索引,然后提取存储在向量中该位置的值。
给定T0、T1和T2类型,我们可以创建包含这三种类型的mpl::vector。现在,我可以使用其他算法在编译时计算索引,并提取存储在向量中该位置的类型。
发布于 2009-06-11 10:52:33
你真的需要区分泛型编程(有点不知道类型)和元编程,元编程是在类型系统中进行计算的一种完全合法的方式。
当你在很多代码中发现一个可泛化的模式时,泛型编程是非常有用的。如果模式中的差异不仅在于变量值,还在于不同的类型,那么泛型编程对于重构代码很有用。
元编程适用于完全不同的领域。这个领域确实很新,需要你自己去探索一下。这也很有趣!
一个非常有用且常见的元编程模式是特征/策略概念。
发布于 2009-06-11 09:58:14
C++模板元编程是一种强大的代码混淆技术,适用于一系列应用程序:
< code >F213
另一种情况:
“泛型编程”(比如STL容器、auto_ptrs等)和“模板元编程”(使用模板系统让编译器有效地“运行算法”)之间的区别是很重要的。
我完全赞成前者,但发现很难看到后者在现实世界中的好处。
https://stackoverflow.com/questions/980206
复制相似问题