Rustでは、抽象化の主なツールはtraitsです。 C++には、抽象化のための2つのツール、抽象クラスとテンプレートがあります。テンプレートを使用することのいくつかの欠点(たとえば、エラーメッセージを読みにくい)を取り除くために、C++は "名前付き要件のセット" であるconceptsを導入しました。
両方の機能はかなり似ているようです:
しかし、私が理解していることから、顕著な違いもあります。たとえば、C++の概念は、関数のシグネチャをリストする代わりに、有効でなければならない一連の式を定義しているようです。しかし、そこにはさまざまで混乱する情報がたくさんあります(たぶん、概念がC++ 20にしか着陸しないためでしょうか?)。それが私が知りたい理由です:C++の概念とRustの特性の違いと類似点は何ですか?
概念または特性のいずれかによってのみ提供される機能はありますか?例えば。 Rustの関連する型と定数についてはどうですか?または、複数の特性/概念によって型の境界を定めていますか?
免責事項:私はまだ概念を使用していません。それらについて知っていることはすべて、さまざまな提案やcppreferenceから収集されたものです。そのため、この答えを詳細に説明してください。
Rustトレイトは、コンパイル時のポリモーフィズムと実行時のポリモーフィズムの両方に使用されます。概念はコンパイル時のポリモーフィズムのみに関するものです。
概念と特性の最大の違いは、概念では構造型を使用するのに対し、特性では名義型を使用することです。
impl Trait for Type
を使用して、型が特性を実装することを明示的に示します。多くの影響があります。一般に、名義型付けは保守性の観点から優れています-特性に要件を追加します-構造型タイピングは、サードパーティのライブラリをブリッジする方が優れています-ライブラリAの型は、ライブラリBの概念を満たすことができますお互いの。
特性は必須です:
概念は完全にオプションです。
注:制約はrequires
句によって導入され、アドホック要件または概念に基づく要件のいずれかを指定します。
表現可能な要件のセットは異なります。
Rustにはアドホックなオーバーロードの概念はありません。オーバーロードはトレイトによってのみ発生し、まだ特殊化はできません。
C++制約を使用して、オーバーロードを最も固有性の低いものから最も固有性の高いものに「順序付け」できるため、コンパイラーは、要件が満たされる最も固有性の高いオーバーロードを自動的に選択できます。
注:これより前は、C++でSFINAEまたはタグディスパッチングを使用して選択を実現していました。オープンエンドのオーバーロードセットを使用するには、体操が必要でした。
この機能の使い方はまだはっきりしていません。
Rust=の要件メカニズムは純粋に付加的です(接続詞、別名&&
)、対照的に、C++では、requires
句に論理和(別名||
)を含めることができます。