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

时间:2019-05-08 17:09:33

标签: c++ rust traits c++-concepts

在Rust中,抽象的主要工具是 traits 。在C ++中,有两种用于抽象的工具:抽象类和模板。为了摆脱使用模板的一些缺点(例如,难以阅读的错误消息),C ++引入了"named sets of requirements"概念

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

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

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

是否只有概念或特征才提供功能?例如。 Rust的关联类型和const呢?还是用多个特征/概念来界定一个类型?

1 个答案:

答案 0 :(得分:16)

免责声明:我还没有使用过概念,我对它们的了解仅来自各种建议和cppreference,因此请一answer而就。

运行时多态性

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

结构与标称。

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

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

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

约束

必须遵守特质:

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

概念完全是可选的:

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

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

要求

可表达要求的集合不同:

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

过载选择

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

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

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

析取

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

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