c++ requires子句怎么写 c++ Concepts约束详解【详解】

发布时间 - 2025-12-30 00:00:00    点击率:
C++20 的 requires 子句是 Concepts 的核心语法,用于编译期静态约束模板参数;常见位置在模板参数后、函数声明前,支持布尔常量表达式、concept 名复用及 requires 表达式检查表达式合法性。

C++ 的 requires 子句用于在模板定义中直接表达对模板参数的约束,它是 C++20 Concepts 的核心语法之一。它不是“写在函数末尾的条件判断”,而是编译期静态检查的声明式约束工具,让错误信息更清晰、接口意图更明确。

requires 子句的基本写法

最常见写法是跟在模板参数列表后、函数声明前,用 requires 关键字引导一个布尔常量表达式:

template
requires std::is_integral_v
T add(T a, T b) { return a + b; }

也可以把约束写成内联形式(更紧凑):

template
  requires std::is_integral_v  // 注意:这里不能加分号
T add(T a, T b) { return a + b; }

注意:requires 后必须是编译期可求值的常量表达式(constexpr bool),不能含运行时变量或非 constexpr 函数调用。

用 concept 名字简化 requires 子句

比起重复写长表达式,推荐先定义 concept,再在 requires 中复用:

template
concept Integral = std::is_integral_v;

template
requires Integral
T add(T a, T b) { return a + b; }

这样语义清晰,也支持逻辑组合:

  • requires Integral && (sizeof(T) > 2)
  • requires Integral || FloatingPoint(需提前定义 FloatingPoint
  • requires !std::is_const_v(带否定)

requires 子句的位置变体

requires 不只出现在函数模板前,还有三种合法位置:

  • 函数模板头之后(最常用):template<...> requires ... void f();
  • 作为函数声明的一部分(尾随 requires)void f() requires C;(适用于类成员函数或已有模板参数推导上下文)
  • 在 template 参数列表中直接约束模板形参template void f(T);(这是 concept 作为类型约束的简写,等价于 template requires Integral

三者语义一致,选哪种取决于可读性和上下文习惯。尾随写法在类内定义成员函数时更自然。

requires 表达式:检查表达式是否合法

除了布尔常量,requires 还支持 requires 表达式(一种特殊的 lambda 式语法),用于检查某表达式能否通过编译:

template
concept Addable = requires(T a, T b) {
  { a + b } -> std::same_as;  // 要求 a+b 存在且返回 T 类型
  { a += b };                        // 只要求能编译,不关心返回值
};

这种写法本质是编译器尝试实例化花括号内的代码块;只要所有子句都满足,整个 requires 表达式为 true。它比 std::is_invocable 等 trait 更灵活,是构建自定义 concept 的主力。

Concepts 和 requires 不是为了炫技,而是让模板错误从“一长串无法理解的内部展开”变成“error: concept 'Integral' not satisfied by 'std::string'”。写清楚约束,既是帮编译器,也是帮下一个读你代码的人。


# 工具  # ai  # c++  # String  # 常量  # 成员函数  # Error  # bool  # void  # 布尔常量  # Lambda  # 接口  # 函数模板  # 形参  # 子句  # 布尔  # 的人  # 复用  # 这是  # 已有  # 出现在  # 适用于  # 它是  # 三种 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Python文件异常处理策略_健壮性说明【指导】  如何用PHP快速搭建CMS系统?  网站制作企业,网站的banner和导航栏是指什么?  如何在IIS中配置站点IP、端口及主机头?  Bootstrap CSS布局之列表  谷歌浏览器下载文件时中断怎么办 Google Chrome下载管理修复  canvas 画布在主流浏览器中的尺寸限制详细介绍  极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?  手机软键盘弹出时影响布局的解决方法  深圳网站制作平台,深圳市做网站好的公司有哪些?  如何在IIS服务器上快速部署高效网站?  Laravel如何自定义分页视图?(Pagination示例)  Laravel如何使用模型观察者?(Observer代码示例)  详解阿里云nginx服务器多站点的配置  Laravel如何使用Contracts(契约)进行编程_Laravel契约接口与依赖反转  php增删改查怎么学_零基础入门php数据库操作必知基础【教程】  Laravel如何实现模型的全局作用域?(Global Scope示例)  Laravel如何使用Spatie Media Library_Laravel图片上传管理与缩略图生成【步骤】  佛山网站制作系统,佛山企业变更地址网上办理步骤?  bootstrap日历插件datetimepicker使用方法  Windows10电脑怎么查看硬盘通电时间_Win10使用工具检测磁盘健康  三星、SK海力士获美批准:可向中国出口芯片制造设备  Laravel怎么使用Blade模板引擎_Laravel模板继承与Component组件复用【手册】  小视频制作网站有哪些,有什么看国内小视频的网站,求推荐?  如何快速搭建高效服务器建站系统?  Laravel如何优化应用性能?(缓存和优化命令)  网站制作软件免费下载安装,有哪些免费下载的软件网站?  高性能网站服务器部署指南:稳定运行与安全配置优化方案  Win11怎么更改系统语言为中文_Windows11安装语言包并设为显示语言  Laravel怎么连接多个数据库_Laravel多数据库连接配置  网站视频制作书签怎么做,ie浏览器怎么将网站固定在书签工具栏?  Laravel如何实现数据库事务?(DB Facade示例)  Windows驱动无法加载错误解决方法_驱动签名验证失败处理步骤  Laravel事件监听器怎么写_Laravel Event和Listener使用教程  美食网站链接制作教程视频,哪个教做美食的网站比较专业点?  Win11搜索不到蓝牙耳机怎么办 Win11蓝牙驱动更新修复【详解】  ,在苏州找工作,上哪个网站比较好?  Laravel项目怎么部署到Linux_Laravel Nginx配置详解  Win11怎么修改DNS服务器 Win11设置DNS加速网络【指南】  Laravel如何与Docker(Sail)协同开发?(环境搭建教程)  Python正则表达式进阶教程_复杂匹配与分组替换解析  Laravel如何实现本地化和多语言支持_Laravel多语言配置与翻译文件管理  使用Dockerfile构建java web环境  想要更高端的建设网站,这些原则一定要坚持!  PHP 500报错的快速解决方法  Laravel API资源类怎么用_Laravel API Resource数据转换  武汉网站设计制作公司,武汉有哪些比较大的同城网站或论坛,就是里面都是武汉人的?  jQuery validate插件功能与用法详解  ,南京靠谱的征婚网站?  如何在万网自助建站中设置域名及备案?