【问题标题】:Why were concepts (generic programming) conceived when we already had classes and interfaces?当我们已经有了类和接口时,为什么还要构思概念(通用编程)?
【发布时间】:2011-09-02 06:11:24
【问题描述】:

Also on programmers.stackexchange.com:

我知道 STL 概念必须存在,并且将它们称为“类”或“接口”是愚蠢的,而实际上它们只是记录在案的(人类)概念,无法翻译成 C++ 代码时间,但是当有机会扩展语言以适应概念时,他们为什么不简单地修改类的功能和/或引入接口?

一个概念是不是非常类似于接口(100% 没有数据的抽象类)?通过观察,在我看来,接口只缺乏对公理的支持,但也许公理可以被引入 C++ 的接口中(考虑在 C++ 中假设采用接口来接管概念),不是吗?我认为即使是汽车概念也可以很容易地添加到这样的 C++ 接口中(汽车接口 LessThanComparable,有人吗?)。

concept_map 是不是非常类似于 Adapter 模式?如果所有方法都是内联的,则适配器在编译时间之后基本上不存在;编译器只是用内联版本替换对接口的调用,在运行时直接调用目标对象。

我听说过一种叫做静态面向对象编程的东西,它本质上意味着在泛型编程中有效地重用面向对象的概念,从而允许使用 OOP 的大部分功能而不会产生执行开销。为什么没有进一步考虑这个想法?

我希望这已经足够清楚了。如果您认为我不是,我可以重写它;请告诉我。

【问题讨论】:

  • 属于programmers.se ?
  • StackOverflow 不再是关于编程了..?离开很久了。
  • @n2liquid:SO 现在似乎更多地是关于技术客观问题和关于基本原理/设计等的主观讨论通常迁移到 SE。真的不知道为什么:p
  • 这对我来说是个新闻。至少 SE 和 SO 一样受欢迎吗?如果不是,我会讨厌 SO/SE >:
  • @n2liquid:当然不是。这就是它如此愚蠢的原因。如果您有一个与编程相关的问题要在此处提出,请继续。可能发生的最糟糕的情况是,人们会因为自己不清楚的原因迁移它。

标签: c++ oop generic-programming c++-concepts


【解决方案1】:

OOP 和泛型编程有很大的区别,宿命

在 OOP 中,当您设计类时,您拥有认为有用的接口。它已经完成了。

另一方面,在通用编程中,只要类符合给定的一组要求(主要是方法,但也包括内部常量或类型),那么它符合要求并且可以使用。 Concept 提案是关于形式化这一点,以便在检查方法签名时直接进行检测,而不是在实例化方法体时。它还使检查模板方法更容易,因为如果概念不匹配,某些方法可以在不进行任何实例化的情况下被拒绝。

Concepts 的优点是你不会受宿命论的困扰,你可以从 Library1 中选择一个类,从 Library2 中选择一个方法,如果合适,你就是黄金(如果不合适,你也许可以使用概念图)。在 OO 中,您每次都需要编写一个成熟的适配器。

你说得对,两者看起来很相似。区别主要在于绑定的时间(事实上,Concept 仍然有静态调度而不是像接口那样的动态调度)。概念更开放,因此更易于使用。

【讨论】:

  • 我知道我们使用 OOP 时会考虑到预定,但我建议改变这种心态。当你写一个概念时,你是在指定需求(即不是你认为会有用,而是对你有用,实际上是必要的)。当您编写我们所知道的界面时,您正在处理预定问题,如果我理解正确的话,我同意。但是,是什么阻止了您在考虑必要性而不是抽象的情况下编写接口?
  • @n2liquid:接口的问题不是抽象的必要性。假设您设计了一个接口interface Comparable { operator<; operator==; },而我过来并想调用一个使用interface LowerThanComparable { operator<; } 的算法,那么我不能使用从您的接口派生的对象,因为您的接口不是从我的接口派生的。这就是我所说的宿命。我不能在我的算法中使用你的对象,除非我有一次为你提供了我的接口。在模块化开发中真的很烦人。
  • @n2liquid:您说的是潜在的自动界面,它会是什么样子?我知道你不会让你的类型符合自动接口,而是算法需要一个自动接口,然后匹配 反对传递给算法的类型的特征,对吗?如果是这样,那么将您的 auto interface 称为 concept 即可。如果你不喜欢有一个新的流行语,那就不要。使用一个新的明显不同的词比在同一个名称下混合不同的概念要好得多。
  • @n2liquid: ... 在添加功能后考虑 SO 中的问题,很多人都在谈论 interfaces 并表示 pure abstract 类和其他人谈论接口并提到您的自动接口。正如您在问题标题中所说,我们已经有了 classesinterfaces 并且它们引用了不同的现有含义,为什么要滥用名称?我们已经有了运行时多态性(virtual,继承)和静态多态性(template)的区别,现在就像你有运行时接口你有静态概念我>
  • @dribeas,是的,你直截了当。你可以回答,我会接受的。任何进一步的讨论都是为什么我更喜欢使用预先存在的概念,这完全是我自己的猜想。这个问题是客观的,你的回答是有效的。我很想讨论更多,但 SO 不是这个地方,我很满意。不过,如果可以的话,我很想知道 C++ 标准背后的人是否有相同的想法,以及他们是否考虑过重用类而不是添加概念。谢谢。
【解决方案2】:

类是命名一致性的一种形式。您通过从I 继承表明类Foo 符合接口I

概念是结构和/或运行时一致性的一种形式。 Foo 类不需要预先声明它符合哪些概念。

结果是命名一致性降低了在预先不期望的地方重用类的能力,即使它们是可用的。

【讨论】:

    【解决方案3】:

    这些概念实际上不是 C++ 的一部分,它们只是概念!在 C++ 中,没有办法“定义一个概念”。您所拥有的只是templates 和classes(STL 都是模板类,顾名思义:S 标准T 模板L 图书馆)。

    如果您指的是 C++0x 而不是 C++(在这种情况下,我建议您更改标签),请在此处阅读:

    http://en.wikipedia.org/wiki/Concepts_(C++)

    有些部分我要复制粘贴给你:

    在 C++ 编程语言的待定 C++0x 修订版中,公理的概念和相关概念是对 C++ 模板系统的提议扩展,旨在改进编译器诊断允许程序员在程序中编写他们编写的模板的一些正式属性。将这些有限的形式规范整合到程序中(除了提高代码清晰度之外)可以指导一些编译器优化,并且可以通过使用形式验证工具潜在地帮助提高程序可靠性检查实现和规范是否真正匹配。

    2009 年 7 月,C++0x 委员会决定从标准草案中删除概念,因为它们被认为“尚未准备好”用于 C++0x。

    引入概念的主要动机是提高编译器错误消息的质量

    如您所见,概念并不是用来代替接口等的,它们只是为了帮助编译器更好地优化并产生更好的错误。

    【讨论】:

    • @n2liquid 你的问题得到答案了吗?
    • C++0x 在 2011 年 3 月成为 C++11(正式 the C++)。 Wikipedia 不是权威的,甚至不是 C++ 信息的良好来源。 “改进编译器诊断”可能具有相当大的革命性意义,因为可测试性是模板编程的主要限制,而且这些消息对许多人来说往往是难以理解的。
    【解决方案4】:

    虽然我同意所有发布的答案,但他们似乎错过了一点,那就是性能。与接口不同,概念是在编译时检查的,因此不需要虚函数调用。

    【讨论】:

      猜你喜欢
      • 2022-01-16
      • 1970-01-01
      • 1970-01-01
      • 2017-11-13
      • 2014-05-09
      • 2015-02-15
      • 2016-05-03
      • 1970-01-01
      • 2016-02-04
      相关资源
      最近更新 更多