共计 2677 个字符,预计需要花费 7 分钟才能阅读完成。
束缚 指定了模板实参须要满足的要求,而 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>::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<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>;
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
};