17
|
Aman Aggarwal Charlie · 技术社区 · 15 年前 |
![]() |
1
30
元编程是一个非常奇特的话题。学习起来很有趣,它是一个强大的工具,偶尔你会发现它很有用。但它永远不会是工具箱中最常用的工具。有时,您可能希望您的代码在一系列具有不同属性的不相关类型上运行,这就是元编程的切入点。通过一点小技巧,您可以编写一个函数的重载,该函数仅在参数类型为整数、指针或X、Y或Z类型(可能忽略Z上的常量)时才可用。 它本质上是用类型编程。通常,您的程序可以做一些事情,比如取两个数字并产生第三个数字,或者告诉您一个数字是否满足某些要求。元编程可以采用两种类型并生成第三种类型,或者告诉您类型是否满足某些要求。是的,它可能在图书馆开发中最有用。但同样,大多数代码 能够 被视为图书馆代码。可以说,main()函数之外的所有内容都是库代码。 通常,如果您想通过元编程解决一个问题,您可能需要使用相关的boost库来完成繁重的工作。Boost.typetraits当然还有Boost.mpl可以为你简化一些事情。但这不是你想要的 需要 要知道,这不是你经常需要的东西。 通用编程是相关的(并且在某些情况下,可以使用引擎盖下的元编程来真正成为通用的,例如,标准库使用一点元编程将原始指针转换为有效的迭代器,“迭代器”概念需要通用的迭代器),但并不完全相同。它的应用也更为广泛。
每次你实例化一个
使用迭代器在序列上迭代的代码是通用的,并且可以使用 任何 迭代器的类型,甚至使用普通指针。 通用编程是非常有用的,并且通常可以在很大程度上取代OOP。(见上述示例。如果我能避免这种限制,为什么我要写一个容器,它需要所包含的类型来实现接口?) 通常,在OOP中使用接口时,不允许在运行时更改类型(当然,这也会不时发生),而是允许您在编译时交换另一个类型(可能在测试期间插入一个模拟对象,而不是使用完整的实现),或者只是分离两个类。通用编程可以做到这一点,而不需要您做定义和维护接口的繁琐工作。在这些情况下,通用编程意味着您必须编写和维护更少的代码,从而获得更好的性能和更好的类型安全性。所以,是的,您应该对通用编程有一种宾至如归的感觉。C++不是一个很好的面向对象编程语言。如果你想严格遵守OOP,你应该切换到Java或其他更多的OOP固定语言。C++ 允许 您可以编写OO代码,但这通常不是最佳解决方案。几乎整个标准库都依赖于通用编程,而不是OOP,这是有原因的。标准库中几乎没有继承或多态性。他们不需要它,没有它,代码就变得更容易使用,更强大。 回答你的其他问题,是的,通用编程基本上是一个独立的范例。模板元编程不是。它是操作类型系统的一种相当具体的技术,非常擅长解决少量的问题。要被认为是一个范例,我认为它必须更普遍地有用,而且基本上你可以使用的方法 一切 如函数、OO或通用编程。 我认为Xtofl确实做到了这一点:通用编程就是让您的代码类型不知道。(标准::矢量没有 照顾 或 需要知道 存储在其中的类型。它只是工作。 另一方面,元编程是关于类型计算的。给定类型t0和t1,我们可以定义类型t2,就像我们如何定义整数n0和n1一样,我们可以定义一个n2,它是n0和n1的和。 mpl库有一个明显的例子。 在普通代码中,如果有整数n0、n1和n2,则可以创建包含这三个值的std::vector。然后我可以使用其他的算法来计算一个索引,然后提取存储在向量中那个位置的值。 给定类型t0、t1和t2,我们可以创建一个包含这三种类型的mpl::vector 类型 . 我现在可以使用其他一些算法在编译时计算索引,并提取 类型 存储在矢量的那个位置。 |
![]() |
2
11
您真的需要区分通用编程(有点不了解类型)和元编程,这是在类型系统中进行计算的一种完全合法的方法。 通用编程是 非常 在许多代码中找到可归纳模式时很有用。如果模式中的差异不仅存在于变量值中,而且也存在于不同的类型中,那么泛型编程对于重构代码非常有用。 元编程适用于完全不同的领域。这个领域确实是非常新的,需要您自己进行一些探索。它 是 太有趣了! 一个非常有用且常见的元编程模式是特性/策略概念。 |
![]() |
3
9
C++模板元编程是一种强大的代码混淆技术,适用于多种应用领域:
另一种情况:
区分“泛型编程”(Stand Stl容器,AutoPyTrS等),这是C++模板设计完成的“模板元编程”(使用模板系统来让编译器有效地为您运行算法”是很重要的。 我都赞成第一种观点,但很难看到第二种观点对现实世界的好处。 |
![]() |
4
5
对于高级模板和技术,我建议: Modern C++ Design ,安德烈·亚历山大·埃斯库 C++是一种严格的语言,几乎没有运行时自省能力。您将遇到的许多问题都可以用模板来处理。此外,模板化语言是图灵完备的,使得在编译时生成复杂的数据结构和预先计算值成为可能。 在许多情况下,这可能比它的价值更麻烦。 |
![]() |
5
3
什么时候? 模板元编程是编写由编译器解释的程序的一种方法。它是一个更高的抽象层次。你可以用它来做各种奇怪和古怪的事情。Boost库包含许多示例:
为什么? 很酷。你可以给约会对象留下深刻印象(也许)。 |
![]() |
6
3
一个尚未给出的答案是:尽管通用编程和元编程确实是彼此截然不同的技术,但它们都是为解决(本质上)相同的问题而设计的:如何摆脱样板文件。这些也体现在软件工程原理的两个首字母缩略词中: DRY (don't repeat yourself) and DIE (duplication is evil) . 这是现代对 Occam's Razor 也就是说,“实体不能无谓地成倍增加”。( 必须有一个非SUNT乘数 )[谁知道14世纪的逻辑学家能想出对21世纪软件设计有用的东西?] 无论如何,这两种技术的要点都是找到将“几乎相同”的代码统一为一段参数化代码的方法。在元编程中,您使用的是代码生成,因此该技术涉及 专攻 特定情况下的一段通用代码(即模板,或更一般的代码生成函数)。在一般编程的情况下,您尝试使用类型系统来识别不同的代码片段是“相同的”,然后使用基于类型的分派进行专门化。 事实证明,这两种技术甚至可以一起用来做一些很花哨的事情。见 Multi-stage programming with functors and monads: eliminating abstraction overhead from generic code 举个例子。但是如果你认为STL很可怕,最好不要看它… |
![]() |
8
1
简单例子:
交换具有相同类型的2个变量的值。 使用模板,我们可以避免为各种类型显式地创建函数 组合 像这样:
上面的函数将由编译器自动创建,在我的示例中,如果在代码中的某个位置调用swap()。 int 或 浮动 变量。 |
![]() |
9
0
我认为,如果您不是库开发人员,那么最好忘记模板元编程。我认为,它在生产代码中是无用的,会带来更多的问题,然后带来好处:“一旦您开始使用它,那么您就失去了绑定到这个解决方案的灵活性。在开始使用模板煮沸的代码之后,很难摆脱它。这是一个问题,因为模板不够灵活”。 当然,我不是指模板容器,交换…但亚历山德里斯科式的密码 |
![]() |
C_Rod · 在模板方法中确定STL容器中项目的数据类型 2 年前 |
![]() |
chenyuandong · Elixir中的元编程 7 年前 |
![]() |
Marcos Felipe · 基于存储的变量进行比较 7 年前 |
![]() |
TheDelChop · 动态定义对象#为Ruby类初始化 7 年前 |
![]() |
Mathieu Van Nevel · 将结构拆分为元组[重复] 7 年前 |
![]() |
Jonathan Mee · 如何防止为未实现方法的对象生成模板 7 年前 |
![]() |
spring cc · 如何在python元编程中使用实例方法? 7 年前 |