[C++] c++20 概念与约束
C++20概念与约束,concept浅谈
·
对于类模板、函数模板、非模板函数可以使用关联约束,这些具名合集称作概念(concept)。每个概念都是谓词,编译期求值(bool)。
template <typename T>
concept is_int = requires{
{ T{} } -> std::same_as<int>;
};
template <is_int T>
void fun(T a) {
}
在编译期对其进行检查。
int main(int argc, char* argv[]) {
std::cout << std::boolalpha << is_int<int> << "\n"; // true
std::cout << std::boolalpha << is_int<double> << "\n"; // false
return 0;
}
概念
定义
概念是要求的具名集合。概念的定义必须在命名空间作用域中出现。
概念定义拥有以下形式:
template < 模板形参列表 >
concept 概念名 = 约束表达式;
概念不能递归,也不能受约束。
例子
看一个标准库中的概念(MSVC 14.3), std::same_as
的实现。
template <class _Ty1, class _Ty2>
concept _Same_impl =
is_same_v<_Ty1, _Ty2>;
template <class _Ty1, class _Ty2>
concept same_as = _Same_impl<_Ty1, _Ty2> && _Same_impl<_Ty2, _Ty1>;
same_as
使用了 std::is_same_v
实现,用于比较两个类型是否完全一致。
std::cout << std::boolalpha << std::same_as<int, int> << "\n"; // true
std::cout << std::boolalpha << std::same_as<double, int> << "\n"; // false
std::cout << std::boolalpha << std::same_as<int&, int> << "\n"; // false
std::cout << std::boolalpha << std::same_as<int*, int> << "\n"; // false
测试代码
结果符合预期。
具体分析 std::same_as
见填坑 (还没写,待填坑)。
特点
- 概念不能被显式实例化、显式特化或部分特化(不能更改约束的原初定义的含义)。
- 概念可以在标识表达式中命名。该标识表达式的值在满足约束表达式时是
true
,否则是false
。 - 概念在“类型约束”中接受的实参要比它的形参列表要求的要少一个,因为按语境推导出的类型会隐式地用作第一个实参。
template <std::same_as<int> T>
constexpr bool is_int_t = false;
会推导出
std::same_as<T, int>
,可以少写一个参数。
更多推荐
已为社区贡献1条内容
所有评论(0)