1. 简介
C++20 引入了 concept 以在编译期检查模板实参是否满足指定的约束.
2. concept
约束指定了模板实参需要满足的要求,而 concept 则是约束的命名集合.
template <template-parameter-list>
concept concept-name = constraint-expression;
此后 concept-name
可以取代 typename
来声明模板形参以添加约束. 也可以将 concept-name<template-parameter-lis>
作为约束表达式的一部分(作为一个约束).
3. 约束
约束指定了模板实参需要满足的要求. 它可以是一个原子约束,或两个约束的逻辑与运算(&&
),或两个约束的逻辑或运算(||
).
原子约束只包含一个表达式,且该表达式的值的类型需要为 bool
(不能经过类型转换). 如果表达式的值为 true
,则满足约束,否则不满足约束.
template <typename T>
requires std::is_arithmetic<T>::value
T add(T x, T y)
{
return x + y;
}
int main()
{
int i = add(1, 2);
double d = add(1.2, 3.4);
}
此处使用 requires
从句(区别于 requires
表达式)来要求 T
必须满足 std::is_arithmetic<T>::value
为 true
. 等价于,
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>;
4. requires 表达式
requires { requirement-seq }
requires ( parameter-list(optional) ) { requirement-seq }
requirements-seq
可以是:简单要求、类型要求、复合要求、嵌套要求.
简单要求
它可以是任意不以 requires
关键字开头的表达式,它断言该表达式是有效的. 只在语言层面上检查该表达式是否有效(编译通过即可),而不会对该表达式进行求值.
template <typename T>
concept Addable = requires (T a, T b)
{
a + b; // a + b 可通过编译即可
};
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';
}
类型要求
具有如下形式:
typename Type
它要求指定的类型 Type
是有效的(存在该类型).
template<typename T> concept C =
requires
{
typename T::inner; // 存在 T::inner 类型
typename S<T>; // 存在指定的模板特化
};
复合要求
具有如下形式:
{ 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 必须有效、存在 T::inner 类型、*x 必须可转换为 T::inner 类型
{*x} -> std::convertible_to<typename T::inner>;
};
嵌套要求
具有如下形式:
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"
};
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。