C++模板—concept

约束指定了模板实参需要满足的要求,而 concept 则是约束的命名集合.

1. concept

template 
concept concept-name = constraint-expression; 

此后 concept-name 可以取代 typename 来声明模板形参以添加约束.
也可以将 concept-name 作为约束表达式的一部分.

2. 约束

约束可以是一个原子约束,或两个约束的逻辑与运算(&&),或两个约束的逻辑或运算(||).

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

template 
requires std::is_arithmetic::value
T 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::valuetrue. 等价于,

template 
concept Arithmetic = std::is_arithmetic::value;

template 
T add(T x, T y)
{
    return x + y;
}

约束的逻辑运算:

template 
concept Integral = std::is_integral::value;

template 
concept SignedIntegral = Integral && std::is_signed::value;
template 
concept Integral = std::is_integral::value;

template 
concept FloatPoint = std::is_floating_point::value;

template 
concept Arithmetic = Integral || FloatPoint;

3. requires 表达式

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

requirements-seq 可以是:简单要求、类型要求、复合要求、嵌套要求.

3.1 简单要求

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

template 
concept Addable = requires (T a, T b)
{
    a + b;    // "the expression a+b is a valid expression that will compile"
};

template 
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 concept C =
requires {
    typename T::inner; // required nested member name
    typename S;     // required class template specialization
};

3.3 复合要求

具有如下形式:

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

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

template concept C2 =
requires(T x) {
    {*x} -> std::convertible_to; // 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; // the expression x + 1 must be valid 
                                  // AND std::same_as must be satisfied
};

3.4 嵌套要求

具有如下形式:

requires constraint-expression ; 

它要求必须满足 constraint-expression.

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

你可能感兴趣的:(c++模板)