命名空间
变体
操作

概念库 (自 C++20 起)

来自 cppreference.com
< cpp

概念库提供了基本库概念的定义,这些概念可用于执行模板参数的编译时验证,并根据类型的属性执行函数分派。这些概念为程序中的等式推理奠定了基础。

标准库中的大多数概念都强制执行语法和语义要求。据说标准概念在满足其语法要求时是满足的,而在满足其语法要求且也满足其语义要求(如果有)时是建模的

通常,只有编译器可以检查语法要求。如果程序的有效性或含义取决于一组模板参数是否对概念建模,而概念满足但未建模,或者在使用时未满足语义要求,则程序格式错误,不需要诊断

内容

[编辑] 等式保持

如果表达式在给定相等输入的情况下产生相等输出,则该表达式为等式保持,其中

  • 输入包括其操作数(不一定使表达式在语义上有效),以及
  • 输出包括其结果以及表达式对操作数的所有修改(如果有)

其中,为便于措辞,“操作数”指的是其最大的子表达式,这些子表达式由id 表达式或对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)
指定一个类型是正规的,也就是说,它既是 semiregular 又是 equality_comparable
(概念) [编辑]
可调用概念
在头文件 <concepts> 中定义
指定可调用类型可以用给定的参数类型集进行调用。
(概念) [编辑]
(C++20)
指定可调用类型是一个布尔谓词。
(概念) [编辑]
(C++20)
指定可调用类型是一个二元关系。
(概念) [编辑]
指定一个 relation 构成一个等价关系。
(概念) [编辑]
指定一个 relation 构成一个严格弱序。
(概念) [编辑]

其他概念可以在 迭代器库算法库范围库 中找到。

[编辑] 参见