Ama*_*wal 17 c++ templates metaprogramming generic-programming
恕我直言,OOPS,设计模式是有道理的,我已经能够实际应用它们.
但是当谈到 Modern C++类的"泛型编程/元编程"时,我感到很困惑.
- 这是一种新的编程/设计范式吗?
- 它仅限于"图书馆开发"吗?如果没有,那么设计/编码情况需要使用元编程/泛型编程.
- 使用模板意味着我正在进行通用编程吗?
我在这个主题上搜索了很多,但没有完全掌握大图.另见这篇文章.
在阅读了这里的讨论之后,到目前为止,我确信(可能仍然不正确):
a)通用编程和元编程是两个不同的概念.
jal*_*alf 30
元编程是一个非常奇特的主题.了解它很有趣,它是一个强大的工具,偶尔你会发现它很有用.但它永远不会是您工具箱中最常用的工具.有时候,您可能希望代码对一系列具有不同属性的不相关类型起作用,这就是元编程的用武之地.通过一些技巧,您可以编写一个函数的重载,只有在参数类型为完整时才可用,或者如果它是指针,或者它是X,Y或Z型(可能忽略Z上的常量).
它本质上是用类型编程的.通常情况下,您的程序可以执行诸如获取两个数字并生成第三个数字之类的操作,或者告诉您数字是否满足某些要求.元编程可以采用两种类型并产生第三种类型,或者告诉您类型是否满足某些要求.是的,它可能在图书馆开发中最有用.但话说回来,大多数代码都可以被视为库代码.你可以说main()函数之外的所有东西都是库代码.
通常,如果您想通过元编程来解决问题,您可能希望使用相关的boost库来完成繁重的工作.Boost.TypeTraits,当然还有Boost.Mpl可以为你简化一些事情.但这不是你需要知道的事情,而且这不是你经常需要的东西.
通用编程是相关的(并且在某些情况下可能使用元编程实现非常通用,例如标准库使用元编程触摸将原始指针转换为有效的迭代器,这是"迭代器"概念通用所必需的) ,但不完全一样.它的使用范围更广泛.
每次实例化时std::vector,都使用泛型编程.每次使用一对迭代器处理一系列值时,都使用泛型编程.通用编程只是这样一种想法,即您的代码应尽可能通用,并且无论放入何种类型,都应该工作.std :: vector不需要包含的类型来实现"ICanBeContained"接口(还记得Java是否需要从Object派生所有内容以便将它存储在容器类中?这意味着原始类型被装箱,并且我们失去了类型安全.这不是通用的,这是一个毫无意义的限制.)
使用迭代器迭代序列的代码是通用的,可以与任何类型的迭代器一起使用,甚至可以使用普通指针.
通用编程非常有用,并且通常可以在很大程度上取代OOP.(参见上面的例子.为什么我会编写一个需要包含类型来实现接口的容器,如果我可以避免这种限制?)
通常,当您在OOP中使用接口时,不允许在运行时更改类型(虽然当然也会不时发生),但是允许您在编译时交换另一种类型(可能注入一个测试期间的模拟对象,而不是使用完整的实现),或仅仅是为了解耦两个类.通用编程可以做到这一点,而无需您完成定义和维护界面的繁琐工作.在这些情况下,通用编程意味着您必须编写和维护更少的代码,并且您可以获得更好的性能和更好的类型安全性.所以,是的,您应该在家中使用通用编程.C++不是一个非常好的OOP语言.如果你想严格遵守OOP,你应该切换到Java或其他更多OOP固定的语言.C++ 允许您编写OO代码,但它通常不是最佳解决方案.这就是为什么几乎整个标准库都依赖于泛型编程而不是OOP的原因.标准库中的遗传或多态性非常少.他们不需要它,代码变得更简单,没有它就更强大.
回答你的其他问题,是的,通用编程几乎是一个单独的范例.模板元编程不是.这是一种操作类型系统的相当具体的技术,非常擅长解决少数问题.要被视为一种范式,我认为它必须更加普遍有用,并且您可以使用的方法基本上用于所有功能,OO或通用编程.
我认为xtofl真的把它钉在了它上面:通用编程就是让你的代码类型 - 不知道.(std :: vector不关心,或者需要知道它中存储了什么类型.它只是起作用.)
另一方面,元编程是关于类型计算.给定类型T0和T1,我们可以定义类型T2,就像我们如何,给定整数N0和N1,我们可以定义一个N2,它是N0和N1的总和.
Boost.Mpl库有一个明显的例子.在普通代码中,如果你有整数N0,N1和N2,你可以创建一个包含这三个值的std :: vector.然后我可以使用其他算法来计算索引,然后提取存储在向量中该位置的值.
给定类型T0,T1和T2,我们可以创建一个包含这三种类型的mpl :: vector .我现在可以使用其他算法在编译时计算索引,并提取存储在向量中该位置的类型.
xto*_*ofl 11
你真的必须区分泛型编程(有点类型 - 不知道)和元编程,这是在类型系统中进行计算的完全合法的方法.
当您在许多代码中找到可推广的模式时,通用编程非常有用.如果模式的差异不仅存在于变量值中,而且存在于不同类型中,则泛型编程对于重构代码很有用.
元编程适用于完全不同的领域.这个领域确实很新,需要一些你自己的探索.这也很有趣!
一个非常有用且常见的元编程模式是特征/政策概念.
Rod*_*ddy 10
C++模板元编程是一种功能强大的代码混淆技术,适用于各种应用:
另一个案例:
"通用编程"(想想STL容器,auto_ptrs等)之间的区别,这是C++模板旨在实现的目标和"模板元编程"(使用模板系统让编译器为您有效地"运行算法")是重要.
我赞成第一个,但很难看到后者带来的实际好处.
| 归档时间: |
|
| 查看次数: |
1910 次 |
| 最近记录: |