束缚指定了模板实参须要满足的要求,而 concept 则是束缚的命名汇合.

1. concept

template <template-parameter-list>concept concept-name = constraint-expression; 

尔后 concept-name 能够取代 typename 来申明模板形参以增加束缚.
也能够将 concept-name<template-parameter-lis> 作为束缚表达式的一部分.

2. 束缚

束缚能够是一个原子束缚,或两个束缚的逻辑与运算(&&),或两个束缚的逻辑或运算(||).

原子束缚只蕴含一个表达式,且该表达式的值的类型须要为 bool(不能通过类型转换). 如果表达式的值为 true,则满足束缚,否则不满足束缚.

template <typename T>requires std::is_arithmetic<T>::valueT add(T x, T y){    return x + y;}int main(){    int i = add(1, 2);    double d = add(1.2, 3.4);    // error    // std::string s(add(std::string("111"), std::string("222")));}

此处应用 requires 从句(区别于 requires 表达式)来要求 T 必须满足 std::is_arithmetic<T>::valuetrue. 等价于,

template <typename T>concept Arithmetic = std::is_arithmetic<T>::value;template <Arithmetic T>T add(T x, T y){    return x + y;}

束缚的逻辑运算:

template <typename T>concept Integral = std::is_integral<T>::value;template <typename T>concept SignedIntegral = Integral<T> && std::is_signed<T>::value;
template <typename T>concept Integral = std::is_integral<T>::value;template <typename T>concept FloatPoint = std::is_floating_point<T>::value;template <typename T>concept Arithmetic = Integral<T> || FloatPoint<T>;

3. requires 表达式

requires { requirement-seq }         requires ( parameter-list(optional) ) { requirement-seq }

requirements-seq 能够是:简略要求、类型要求、复合要求、嵌套要求.

3.1 简略要求

它能够是任意不以 requires 关键字结尾的表达式,它断言该表达式是无效的. 只在语言层面上查看该表达式是否无效(编译通过即可),而不会对该表达式进行求值.

template <typename T>concept Addable = requires (T a, T b){    a + b;    // "the expression a+b is a valid expression that will compile"};template <Addable T>T add(T x, T y){    return x + y;}int main(){    std::cout << add(1, 2) << '\n';    std::cout << add(std::string("111"), std::string("222")) << '\n';}

3.2 类型要求

具备如下模式:

typename Type

它要求指定的类型 Type 是无效的(存在该类型).

template<typename T> concept C =requires {    typename T::inner; // required nested member name    typename S<T>;     // required class template specialization};

3.3 复合要求

具备如下模式:

{ expression } noexcept(optional) return-type-requirement(optional) ;         return-type-requirement: -> type-constraint

它要求 expression 是无效的, 而且 decltype((expression)) 必须满足 type-constraint.

template<typename T> concept C2 =requires(T x) {    {*x} -> std::convertible_to<typename T::inner>; // the expression *x must be valid                                                    // AND the type T::inner must be valid                                                    // AND the result of *x must be convertible to T::inner    {x + 1} -> std::same_as<int>; // the expression x + 1 must be valid                                   // AND std::same_as<decltype((x + 1)), int> must be satisfied};

3.4 嵌套要求

具备如下模式:

requires constraint-expression ; 

它要求必须满足 constraint-expression.

template <class T>concept Semiregular = DefaultConstructible<T> &&    CopyConstructible<T> && Destructible<T> && CopyAssignable<T> &&requires(T a, size_t n) {      requires Same<T*, decltype(&a)>;  // nested: "Same<...> evaluates to true"    { a.~T() } noexcept;  // compound: "a.~T()" is a valid expression that doesn't throw    requires Same<T*, decltype(new T)>; // nested: "Same<...> evaluates to true"    requires Same<T*, decltype(new T[n])>; // nested    { delete new T };  // compound    { delete new T[n] }; // compound};