名稱空間
變體
操作

概念庫 (C++20 起)

來自 cppreference.com
< cpp

概念庫提供了基本庫概念的定義,這些概念可用於對模板引數執行編譯時驗證,並根據型別的屬性執行函式分派。這些概念為程式中的等式推理提供了基礎。

標準庫中的大多數概念都施加了句法和語義要求。如果滿足其句法要求,則稱標準概念為 _satisfied_;如果滿足其句法要求並且也滿足其語義要求(如果有),則稱其為 _modeled_。

通常,只有句法要求可以由編譯器檢查。如果程式的有效性或含義取決於模板引數序列是否 _models_ 一個概念,並且該概念被 _satisfied_ 但未被 _modeled_,或者如果在使用點未滿足語義要求,則程式格式錯誤,無需診斷

目錄

[編輯] 相等性保持

如果一個表示式在給定相等輸入時產生相等輸出,則稱該表示式是 _equality-preserving_ 的,其中

  • 輸入由其運算元組成(不一定使表示式在語義上有效),並且
  • 輸出由其結果以及表示式對運算元(如果有)的所有修改組成

為方便起見,其“運算元”指其最大的子表示式,這些子表示式由 id-expression 或對 std::movestd::forwardstd::declval 的呼叫組成。

每個運算元的 cv 限定和值類別透過假設其型別中的每個模板型別引數表示一個 cv 非限定的完整非陣列物件型別來確定。

所有要求相等性保持的表示式還要求是穩定的,即,兩次使用相同輸入物件進行求值必須產生相等輸出,而無需對這些輸入物件進行任何顯式中間修改。

除非另有說明,否則標準庫概念requires 表示式中使用的每個表示式都要求是相等性保持的,並且表示式的求值只能修改其非常量運算元。常量運算元不得修改。

在標準庫中,以下概念允許具有非相等性保持的 requires 表示式

[編輯] 隱式表示式變體

一個 requires 表示式,如果它使用了對某個常量左值運算元不進行修改的表示式,則它也隱式地要求該表示式的額外變體,這些變體接受非常量左值或(可能是常量)右值作為給定運算元,除非明確要求具有不同語義的此類表示式變體。

這些 _隱式表示式變體_ 必須滿足宣告表示式的相同語義要求。實現驗證變體語法的程度未指定。

template<class T>
concept C = requires(T a, T b, const T c, const T d)
{
    c == d;           // expression #1: does not modify the operands
    a = std::move(b); // expression #2: modifies both operands
    a = c;            // expression #3: modifies the left operand `a`
};
 
// Expression #1 implicitly requires additional expression variations that
// meet the requirements for c == d (including non-modification),
// as if the following expressions had been declared as well:
 
// ------ const == const ------- ------ const == non-const ---
//                                         c  ==           b;
//            c == std::move(d);           c  == std::move(b);
// std::move(c) ==           d;  std::move(c) ==           b;
// std::move(c) == std::move(d); std::move(c) == std::move(b);
 
// -- non-const == const ------- -- non-const == non-const ---
//           a  ==           d;            a  ==           b;
//           a  == std::move(d);           a  == std::move(b);
// std::move(a) ==           d;  std::move(a) ==           b;
// std::move(a) == std::move(d); std::move(a) == std::move(b);
 
// Expression #3 implicitly requires additional expression variations that
// meet the requirements for a = c
// (including non-modification of the second operand),
// as if the expressions a = b (non-constant lvalue variation)
// and a = std::move(c) (const rvalue variation) had been declared.
 
// Note: Since expression #2 already requires the non-constant rvalue variation
// (a == std::move(b)) explicitly, expression #3 does not implicitly require it anymore.
 
// The type T meets the explicitly stated syntactic requirements of
// concept C above, but does not meet the additional implicit requirements
// (i.e., T satisfies but does not model C):
// a program requires C<T> is ill-formed (no diagnostic required).
struct T
{
    bool operator==(const T&) const { return true; }
    bool operator==(T&) = delete;
};

[編輯] 標準庫概念

定義於名稱空間 std
核心語言概念
定義於標頭檔案 <concepts>
(C++20)
指定型別與另一型別相同
(概念) [編輯]
指定型別派生自另一型別
(概念) [編輯]
指定型別可隱式轉換為另一型別
(概念) [編輯]
指定兩種型別共享一個共同的引用型別
(概念) [編輯]
指定兩種型別共享一個共同的型別
(概念) [編輯]
(C++20)
指定型別是整型
(概念) [編輯]
指定型別是帶符號的整型
(概念) [編輯]
指定型別是無符號的整型
(概念) [編輯]
指定型別是浮點型別
(概念) [編輯]
指定型別可從另一型別賦值
(概念) [編輯]
指定型別可以被交換,或者兩種型別可以互相交換
(概念) [編輯]
指定該型別的物件可以被銷燬
(概念) [編輯]
指定該型別的變數可以從一組引數型別構造或繫結
(概念) [編輯]
指定型別的物件可以預設構造
(概念) [編輯]
指定型別的物件可以被移動構造
(概念) [編輯]
指定型別的物件可以被複制構造和移動構造
(概念) [編輯]
比較概念
定義於標頭檔案 <concepts>
 (C++20)
指定型別可以在布林上下文中使用
(僅用於闡釋的概念*)[編輯]
指定運算子 == 是等價關係
(概念) [編輯]
指定型別上的比較運算子產生全序關係
(概念) [編輯]
定義於標頭檔案 <compare>
指定運算子 <=> 在給定型別上產生一致的結果
(概念) [編輯]
物件概念
定義於標頭檔案 <concepts>
(C++20)
指定型別的物件可以被移動和交換
(概念) [編輯]
(C++20)
指定型別的物件可以被複制、移動和交換
(概念) [編輯]
指定型別的物件可以被複制、移動、交換和預設構造
(概念) [編輯]
(C++20)
指定型別是 _regular_ 的,即它既是 semiregular 又是 equality_comparable
(概念) [編輯]
可呼叫概念
定義於標頭檔案 <concepts>
指定可呼叫型別可以使用給定的一組引數型別進行呼叫
(概念) [編輯]
(C++20)
指定可呼叫型別是布林謂詞
(概念) [編輯]
(C++20)
指定可呼叫型別是二元關係
(概念) [編輯]
指定 relation 施加等價關係
(概念) [編輯]
指定 relation 施加嚴格弱序
(概念) [編輯]

更多概念可以在迭代器庫演算法庫範圍庫中找到。

[編輯] 另見