Skip to content

Latest commit

 

History

History
171 lines (120 loc) · 10.5 KB

concepts.md

File metadata and controls

171 lines (120 loc) · 10.5 KB

concepts

  • concepts[meta header]
  • cpp20[meta cpp]

概要

<concepts>ヘッダでは基礎的なコンセプトの実装を提供する。これらのコンセプトは標準ライブラリでも使用される。

本ヘッダはフリースタンディング環境でも提供される。

暗黙の意味論的な制約

等しさの保持(equality preservation

ある式への等しい入力によって等しい出力が得られる時、その式は 等しさを保持 している。入力とはその式に与えられた全ての引数(オペランド)であり、出力とはその式の結果およびその式によって変更された全ての引数のこと。

また、必ずしも入力の個別の値が全てその式にとって有効である必要はない。例えば、整数に対するa / bという式は等しさを保持するが、b = 0の時この式は有効ではない。しかし、このことは式a / bが等しさを保持することを妨げない。
式への入力のうちこのような有効ではない値を除いたものをその式の 定義域(domain と呼ぶ。

等しさを保持する式はさらに 安定(stable でなければならない。式が安定であるとは、その式への同じオブジェクトの入力は、そのオブジェクトの明示的な変更が介在しない限りは常に同じ出力が得られることである。
式が安定であれば、あるオブジェクトの現在の値についてのことを、等しさを保持する式を介して観測した以前の値についての情報から推察することができる。

つまりこれらの事は、式が引数と結果以外に副作用を及ぼさず、式内部に状態を持たず、式の実行にはその外部からの影響がないことを要求している。

そして、C++標準においてrequires式で使用される全ての式は等しさを保持し安定でなければならない。この事は、場合によっては間接的にユーザーコードに対しても要求される。ただし、「等しさを保持することを要求しない」などと明記されている場合にはその必要はない。

式の入力への副作用

C++標準で定義されるrequires式では、それぞれの制約式への入力が(その制約式が実際に実行された場合に)変更されるかどうかをrequires式のローカルパラメータのconst修飾によって表現する。別に記載のある場合を除いて、const修飾のない左辺値・右辺値のローカルパラメータは変更しても良く変更されうる事を、const修飾されたパラメータは変更してはならず変更されない事を表明する。

template<typename T>
concept C1 = requires(T a) {
  a + a;  // C1コンセプトを満たす型はこの式の実行においてその引数を変更しても良い
};

template<typename T>
concept C2 = requires(const T a) {
  a + a;  // C2コンセプトを満たす型はこの式の実行においてその引数を変更してはならない
};

これによって各制約式では、型パラメータがCV修飾されない非配列のオブジェクト型であると仮定することで、それぞれの引数の値カテゴリとCV修飾を確定することができる。

暗黙的な式のバリエーション(implicit expression variations

requires式において定数左辺値としてローカルパラメータを宣言する場合、それぞれの制約式にはそのパラメータを受け取る位置に非定数左辺値や(定数)右辺値を受け入れる暗黙的な式のバリエーションが要求される。ただし、このような暗黙的な式のバリエーション(のいずれか)が異なる意味論を持ち、明示的に記述される場合を除く。

この暗黙的な式のバリエーションは各制約式の意味論的な要件を満たすために必要である。ただし、実装が各バリエーションをどこまで構文的に検証するかについては未規定。

// このCコンセプトは
template<typename T>
concept C = requires(const T a, T b) {
  a + b;
};

// 以下のようなバリエーションが全て有効であることを暗黙的に要求している(実際にこのように検証されるかは未規定)
template<typename T>
concept C =
  requires(const T a, T b) { a + b } &&
  requires(T a, T b) { a + b; } &&
  requires(T&& a, T b) { std::move(a) + b; } &&
  requires(const T&& a, T b) { std::move(a) + b; };

コンセプトのモデル

TがあるコンセプトCの構文的な制約(コンセプト定義内の各制約式)を全て満足しそれら制約式の追加の暗黙の意味論的な制約(等しさの保持、安定、入力への副作用の要求および暗黙的な式のバリエーション)についても全て満足していて、Cに追加で要求されている意味論的な制約(モデルとなる条件)を全て満足するとき、そのような型TはコンセプトCモデル(model である。

モデルとなるための意味論的な制約は文書で指定されているのみであり、通常何らかのチェックは行われない。しかし、標準ライブラリの事前条件などにおいて入力に対してあるコンセプトのモデルである事を要求する場合、モデルとならない型の入力は診断不要の未定義動作となる。

本サイトでは、型がコンセプトのモデルとなるための条件をそのコンセプトの構文的な制約条件とは分けて「モデル」という項に記載する。

型の関係

名前 説明 対応バージョン
same_as 2つの型が同じ C++20
derived_from 継承関係にある C++20
convertible_to 変換可能 C++20
common_reference_with 共通の参照型 C++20
common_with 共通の型 C++20

型の種類

名前 説明 対応バージョン
integral 整数型 C++20
signed_integral 符号付き整数型 C++20
unsigned_integral 符号なし整数型 C++20
floating_point 浮動小数点数型 C++20

型の構築・破棄・代入操作

名前 説明 対応バージョン
constructible_from 構築可能 C++20
default_initializable デフォルト構築可能 C++20
copy_constructible コピー構築可能 C++20
move_constructible ムーブ構築可能 C++20
destructible 破棄可能 C++20
assignable_from 代入可能 C++20
swappable 入れ替え可能 C++20
swappable_with 特定の型と入れ替え可能 C++20

比較

名前 説明 対応バージョン
equality_comparable 等値比較可能 C++20
equality_comparable_with 特定の型と等値比較可能 C++20
totally_ordered 狭義の全順序による比較が可能 C++20
totally_ordered_with 特定の型と狭義の全順序による比較が可能 C++20

値指向の操作

名前 説明 対応バージョン
movable ムーブ可能 C++20
copyable コピー可能 C++20
semiregular 半正則 C++20
regular 正則 C++20

関数呼び出し

名前 説明 対応バージョン
invocable INVOKEコンセプトに従った関数呼び出しが可能 C++20
regular_invocable 正則呼び出し可能 C++20
predicate 述語 C++20
relation 二項関係 C++20
equivalence_relation 同値関係 C++20
strict_weak_order 狭義の弱順序 C++20

カスタマイゼーションポイントオブジェクト

名前 説明 対応バージョン
ranges::swap 任意の2つのオブジェクトを入れ替える C++20

そのうちどこかに移動するページ

以下は、ライブラリとして提供はされていない要件をまとめる。

名前 説明
Callable
INVOKE
LessThanComparable 小なり比較可能
ValueSwappable 間接参照して入れ替え可能
CopyAssignable コピー代入可能
MoveAssignable ムーブ代入可能

関連項目

参照