[C++] c++20 概念与约束

对于类模板、函数模板、非模板函数可以使用关联约束,这些具名合集称作概念(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> ,可以少写一个参数。

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值