繁体   English   中英

C ++的概念和Rust的特征之间有什么相似之处和不同之处?

[英]What are the similarities and differences between C++'s concepts and Rust's traits?

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

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

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

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

是否存在仅由概念或特征提供的功能? 比如Rust的相关类型和consts怎么样? 或者通过多个特征/概念绑定一个类型?

免责声明:我还没有使用过概念,我所知道的所有概念都是从各种提案和cppreference中收集的,所以请大家用这个答案。

运行时多态性

Rust Traits既用于编译时多态,也用于运行时多态; 概念只是关于编译时多态性。

结构与名义。

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

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

有许多后果; 一般来说,从可维护性的角度来看,名义打字更好 - 向特征添加一个要求 - 而结构打字更好地是一个桥接的第三方库 - 来自库A的类型可以满足来自库B的概念而无需他们意识到彼此的。

约束

特征是强制性的:

  • 如果不需要此类型来实现提供该方法的特征,则不能对泛型类型的变量调用任何方法。

概念完全是可选的:

  • 可以在泛型类型的变量上调用方法,而不需要此类型来满足任何概念,或以任何方式约束。
  • 可以在满足Concept(或几个)的泛型类型的变量上调用方法,而不由任何Concept或Constraint指定该方法。
  • 约束(参见注释)可以完全是临时的,并且在不使用命名概念的情况下指定需求; 再一次,它们完全是可选的。

注意:约束由requires子句引入,并指定ad-hoc要求或基于Concepts的要求。

要求

一组可表达的要求是不同的:

  • 概念/约束通过替换来工作,因此允许整个语言的广度; 要求包括:嵌套类型/常量/变量,方法,字段,用作另一个函数/方法的参数的能力,用作另一种类型的泛型参数的能力,以及它们的组合。
  • 相比之下,特征只允许一小组要求:关联的类型/常量和方法。

过载选择

Rust没有ad-hoc重载的概念,只有Traits才会发生重载,而且还不能进行专门化。

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

注意:在此之前,要么在C ++中使用SFINAE或标签调度来实现选择; 健美操需要使用开放式过载套件。

析取

如何使用此功能还不是很清楚。

鲁斯特要求机制是纯加(连词,又名&& ),与此相反,在C ++ requires条款可以包含析取(又名|| )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM