C ++的概念和Rust的特征之间有什么异同?

Luk*_*odt 37 c++ traits rust c++-concepts

在Rust中,抽象的主要工具是traits。在C ++中,有两种用于抽象的工具:抽象类和模板。为了摆脱一些使用模板的缺点(例如,硬盘读取错误消息),C ++引入的概念,这是“命名集的要求”

这两个功能似乎非常相似:

  • 定义特征/概念是通过列出要求来完成的。
  • 两者都可以用于绑定/限制通用/模板类型参数。
  • Rust特征和带有概念的C ++模板都是单态化的(我知道Rust特征也可以用于动态调度,但这是另外一回事了)。

但据我了解,也存在显着差异。例如,C ++的概念似乎定义了一组必须有效的表达式,而不是列出函数签名。但是那里有很多不同且令人困惑的信息(也许是因为概念仅出现在C ++ 20中?)。这就是为什么我想知道:C ++概念和Rust的特性之间的区别和相似之处到底是什么?

是否存在仅概念或特征提供的功能?例如,Rust的关联类型和const如何?还是用多个特征/概念来界定一个类型?

Mat*_* M. 20

免责声明:我还没有使用过概念,我对它们所了解的全部来自各种建议和建议,因此,请一筹莫展。

运行时多态

Rust特性既用于编译时多态,有时也用于运行时多态。概念仅与编译时多态有关。

结构与标称。

概念和特征之间的最大区别在于概念使用结构化类型,而特征使用名义类型

  • 在C ++中,类型从不明确地满足概念。如果碰巧满足所有要求,它可能“偶然地”满足它。
  • 在Rust中,特定的语法构造impl Trait for Type用于显式指示类型实现了Trait。

有很多后果。通常,从可维护性的角度来看,标称键入更好-对特质增加了要求-而结构化键入更好地桥接了第三方库-库A的类型可以满足库B的概念而无需他们知道彼此的。

约束条件

特质是强制性的:

  • 除非实现提供该方法的特征所必需的类型,否则不能在泛型类型的变量上调用任何方法。

概念完全是可选的:

  • 可以在通用类型的变量上调用方法,而无需满足任何概念或以任何方式对其进行约束。
  • 可以在满足概念(或多个概念)的泛型类型的变量上调用方法,而无需由任何概念或约束指定该方法。
  • 约束(请参见注释)可以是完全临时的,无需使用命名的Concept即可指定要求;再一次,它们是完全可选的。

注意:约束是由requires子句引入的,用于指定临时要求或基于概念的要求。

要求

可表达的要求集是不同的:

  • 概念/约束通过替换起作用,因此允许语言的全部宽度;要求包括:嵌套类型/常量/变量,方法,字段,用作另一个函数/方法的自变量的能力,用作另一个类型的泛型自变量的能力及其组合。
  • 相比之下,特征仅允许一小部分要求:关联的类型/常量和方法。

过载选择

Rust没有临时重载的概念,重载仅由Traits发生,并且无法进行专门化。

C ++约束可用于按从最不特定到最特定的顺序对重载进行“排序”,因此编译器可以自动选择满足要求的最特定的重载。

注意:在此之前,在C ++中将使用SFINAE或标记分派来实现选择;健美操需要使用开放式过载组。

析取

我还不太清楚如何使用此功能。

Rust中的需求机制是纯加性的(conjunctions,aka &&),相比之下,在C ++ requires子句中可以包含析取项(aka ||)。

  • @RalfJung:在C ++中,这将是静态成员变量(常量变量)和嵌套的typedef或嵌套的类。 (2认同)