C++模板编程——可变参函数模板之折叠表达式

目录

1. 什么是折叠表达式

2. 一元左折

3. 一元右折

4. 二元左折

5. 二元右折

6. 后记


上一节主要讲解了可变参函数模板和参数包展开,这一节主要讲一下折叠表达式。

1. 什么是折叠表达式

折叠表达式是C++17中引入的概念,引入折叠表达式的目的是为了计算某个值。这跟可变参有关。

上一节提到了递归展开参数包,通过递归调用的方式可以一个一个地拿到每一个参数并进行处理。

折叠表达式允许我们一次性让所有参数参与计算

让我们来看代码感受一下:

#include <iostream>using namespace std;template<typename... T>
auto add_all(T... args)
{return (... + args); // 圆括号不可以省略,圆括号中的内容就是折叠表达式
}int main()
{cout << add_all(1, 2, 3, 4, 5) << endl;
}

运行结果如下图所示:

从结果可以看到,add_all(1,2,3,4,5)的结果是(1+2+3+4+5)的求和结果。

return 语句后面的圆括号中的内容就是折叠表达式


折叠表达式一般有4种格式,每种格式都是用圆括号括起来。

  • 一元左折
  • 一元右折
  • 二元左折
  • 二元右折

左折就是参数从左侧开始计算,右折就是参数从右侧开始计算。

现在不理解没关系,下面会详细介绍。

2. 一元左折

一元左折的格式为:(... 运算符 一包参数)

计算过程为:(((参数1 运算符 参数2) 运算符 参数3) ... 运算符 参数N)

这种形式的三个点在开头,中间是运算符,一包参数在右侧,整体用圆括号括起来的形式就是一元左折。

上面代码中演示的就是一元左折的形式。下面再举个别的例子。

#include <iostream>using namespace std;template<typename... T>
auto mul_all(T... args)
{return (... * args);
}int main()
{cout << mul_all(1, 2, 3) << endl;// ((1+2)+3) = 6
}

运行结果如下图所示:

mul_all函数中的(... * args)就是一元左折。

理解起来应该很容易,其中运算符可以换成其他的,可以编写代码尝试一下。

一元左折就先介绍到这里。

3. 一元右折

一元左折的格式为:(一包参数 运算符 ...)

计算过程为:(参数1 ... (数N-2 运算符(参数N-1 运算符 参数N)))

一元右折和一元左折的格式非常相似,只是一包参数的位置和...的位置反了过来。

计算过程变成了从右侧开始计算。

这里再强调一次,左折就是参数从左侧开始计算,右折就是参数从右侧开始计算。

下面再给一个具体的代码示例:

#include <iostream>using namespace std;template<typename... T>
auto sub_all_left(T... args) // 一元左折
{return (... - args);
}template<typename... T>
auto sub_all_right(T... args) // 一元右折
{return (args - ...);
}int main()
{cout << sub_all_left(1, 2, 3) << endl; // ((1-2)-3) = -4cout << sub_all_right(1, 2, 3) << endl; // (1-(2-3)) = 2
}

这里展示了一元左折和一元右折的减法运算符的实现,运行结果如下图所示:

代码比较好理解,不太理解的话仔细看看注释和前面的文字,帮助理解。

一元右折就介绍到这里。

4. 二元左折

二元左折的格式为:(init 运算符 ... 运算符 一包参数)

计算过程为:((((init 运算符 参数1) 运算符 参数2) 运算符 参数3) ... 运算符 参数N)

其中,init相当于一个初始值,也可以是一个对象什么的,只要能参与运算符的运算就可以。

下面看一段代码帮助理解:

#include <iostream>using namespace std;template<typename U, typename... T>
auto sub_all_left_with_init(U init, T... args) // 二元左折
{return (init - ... - args);
}int main()
{int init = 10;cout << sub_all_left_with_init(init, 2, 3, 4) << endl; // ((((init-2))-3)-4)=1
}

运行结果如下图所示:


上面那个例子看完之后,再来看看这个例子,启发一下。

#include <iostream>
using namespace std;template<typename... T>
void print_all(T... args)
{(cout << ... << args) << endl;
}int main()
{print_all(1, 2, 3, 4, 5); // 12345
}

运行结果如下图所示:

因为cout << arg的返回值仍然是cout,所以二元左折可以进行,好好体会一下。

5. 二元右折

二元左折的格式为:(一包参数 运算符 ... 运算符 init)

计算过程为:(参数1 ... (参数N-2 运算符 (参数N-1 运算符 (参数N 运算符 init ))))

跟二元左折很类似,直接上代码感受一下吧:

#include <iostream>using namespace std;template<typename U, typename... T>
auto sub_all_right_with_init(U init, T... args) // 二元右折
{return (args - ... - init);
}int main()
{int init = 10;cout << sub_all_right_with_init(init, 2, 3) << endl;//(2-(3-init)) = 9
}

运行结果如图所示:

6. 后记

到这里四种折叠表达式就介绍完毕了,每种都给了讲解和代码示例。有不懂的地方欢迎评论区提问

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

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

相关文章

python学opencv|读取图像(五十三)原理探索:使用cv.matchTemplate()函数实现最佳图像匹配

【1】引言 前序学习进程中&#xff0c;已经探索了使用cv.matchTemplate()函数实现最佳图像匹配的技巧&#xff0c;并且成功对两个目标进行了匹配。 相关文章链接为&#xff1a;python学opencv|读取图像&#xff08;五十二&#xff09;使用cv.matchTemplate()函数实现最佳图像…

《AI大模型开发笔记》DeepSeek技术创新点

一、DeepSeek横空出世 DeepSeek V3 以颠覆性技术架构创新强势破局&#xff01;革命性的上下文处理机制实现长文本推理成本断崖式下降&#xff0c;综合算力需求锐减90%&#xff0c;开启高效 AI 新纪元&#xff01; 最新开源的 DeepSeek V3模型不仅以顶尖基准测试成绩比肩业界 …

Sqoop导入MySQL中含有回车换行符的数据

个人博客地址&#xff1a;Sqoop导入MySQL中含有回车换行符的数据 MySQL中的数据如下图&#xff1a; 检查HDFS上的目标文件内容可以看出&#xff0c;回车换行符位置的数据被截断了&#xff0c;导致数据列错位。 Sqoop提供了配置参数&#xff0c;在导入时丢弃掉数据的分隔符&…

标准IO与文件IO 进程与线程

标准IO与文件IO 进程与线程

Go学习:Go语言中if、switch、for语句与其他编程语言中相应语句的格式区别

Go语言中的流程控制语句逻辑结构与其他编程语言类似&#xff0c;格式有些不同。Go语言的流程控制中&#xff0c;包括if、switch、for、range、goto等语句&#xff0c;没有while循环。 目录 1. if 语句 2. switch语句 3. for语句 4. range语句 5. goto语句&#xff08;不常用…

【网络】传输层协议TCP(重点)

文章目录 1. TCP协议段格式2. 详解TCP2.1 4位首部长度2.2 32位序号与32位确认序号&#xff08;确认应答机制&#xff09;2.3 超时重传机制2.4 连接管理机制(3次握手、4次挥手 3个标志位)2.5 16位窗口大小&#xff08;流量控制&#xff09;2.6 滑动窗口2.7 3个标志位 16位紧急…

小程序的协同工作与发布

1.小程序API的三大分类 2.小程序管理的概念&#xff0c;以及成员管理两个方面 3.开发者权限说明以及如何维护项目成员 4.小程序版本

【MySQL】语言连接

语言连接 一、下载二、mysql_get_client_info1、函数2、介绍3、示例 三、其他函数1、mysql_init2、mysql_real_connect3、mysql_query4、mysql_store_result5、mysql_free_result6、mysql_num_fields7、mysql_num_rows8、mysql_fetch_fields9、mysql_fetch_row10、mysql_close …

c语言进阶(简单的函数 数组 指针 预处理 文件 结构体)

c语言补充 格式 void函数头 {} 中的是函数体 sum函数名 &#xff08;&#xff09; 参数表 #include <stdio.h>void sum(int begin, int end) {int i;int sum 0;for (i begin ; i < end ; i) {sum i;}printf("%d到%d的和是%d\n", begin, end, sum); …

FastAPI + GraphQL + SQLAlchemy 实现博客系统

本文将详细介绍如何使用 FastAPI、GraphQL&#xff08;Strawberry&#xff09;和 SQLAlchemy 实现一个带有认证功能的博客系统。 技术栈 FastAPI&#xff1a;高性能的 Python Web 框架Strawberry&#xff1a;Python GraphQL 库SQLAlchemy&#xff1a;Python ORM 框架JWT&…

实验9 JSP访问数据库(二)

实验9 JSP访问数据库&#xff08;二&#xff09; 目的&#xff1a; 1、熟悉JDBC的数据库访问模式。 2、掌握预处理语句的使用 实验要求&#xff1a; 1、使用Tomcat作为Web服务器 2、通过JDBC访问数据库&#xff0c;实现增删改查功能的实现 3、要求提交实验报告&#xff0c;将代…

扣子平台音频功能:让声音也能“智能”起来。扣子免费系列教程(14)

在数字化时代&#xff0c;音频内容的重要性不言而喻。无论是在线课程、有声读物&#xff0c;还是各种多媒体应用&#xff0c;音频都是传递信息、增强体验的关键元素。扣子平台的音频功能&#xff0c;为开发者和内容创作者提供了一个强大而灵活的工具&#xff0c;让音频的使用和…

小程序项目-购物-首页与准备

前言 这一节讲一个购物项目 1. 项目介绍与项目文档 我们这里可以打开一个网址 https://applet-base-api-t.itheima.net/docs-uni-shop/index.htm 就可以查看对应的文档 2. 配置uni-app的开发环境 可以先打开这个的官网 https://uniapp.dcloud.net.cn/ 使用这个就可以发布到…

Unity游戏(Assault空对地打击)开发(3) 摄像机的控制

详细步骤 打开My Assets或者Package Manager。 选择Unity Registry。 搜索Cinemachine&#xff0c;找到 Cinemachine包&#xff0c;点击 Install按钮进行安装。 关闭窗口&#xff0c;新建一个FreeLook Camera&#xff0c;如下。 接着新建一个对象Pos&#xff0c;拖到Player下面…

UE编辑器工具

如何自己制作UE小工具提高工作效率 在虚幻编辑器用户界面中&#xff0c;可以使用各种各样的可视化工具来设置项目&#xff0c;设计和构建关卡&#xff0c;创建游戏性交互等等。但有些时候&#xff0c;当你确定了需要编辑器执行的操作后&#xff0c;可能想要通过编程方式调用它…

PVE 中 Debian 虚拟机崩溃后,硬盘数据怎么恢复

问题 在 PVE 中给 Debian 虚拟机新分配硬盘后&#xff0c;通过 Debian 虚拟机开启 Samba 共享该硬盘。如果这个 Debian 虚拟机崩溃后&#xff0c;怎么恢复 Samba 共享硬盘数据。 方法 开启 Samba 共享相关知识&#xff1a;挂载硬盘和开启Samba共享。 新建一个虚拟机&#xf…

微信登录模块封装

文章目录 1.资质申请2.combinations-wx-login-starter1.目录结构2.pom.xml 引入okhttp依赖3.WxLoginProperties.java 属性配置4.WxLoginUtil.java 后端通过 code 获取 access_token的工具类5.WxLoginAutoConfiguration.java 自动配置类6.spring.factories 激活自动配置类 3.com…

Games104——网络游戏的进阶架构

这里写目录标题 前言位移移动插值内插&#xff08;Interpolation&#xff09;外插&#xff08;Extrapolation&#xff09; 命中判定Hit Registration在客户端去判定 在服务器端去判定延迟补偿掩体问题躲进掩体走出掩体 技能前摇本地暴击效果 基础MMO框架分布式架构一致性哈希服…

SQL Server查询计划操作符(7.3)——查询计划相关操作符(5)

7.3. 查询计划相关操作符 38)Flow Distinct:该操作符扫描其输入并对其去重。该操作符从其输入得到每行数据时即将其返回(除非其为重复数据行,此时,该数据行会被抛弃),而Distinct操作符在产生任何输出前将消费所有输入。该操作符为逻辑操作符。该操作符具体如图7.2-38中…

Jenkins未在第一次登录后设置用户名,第二次登录不进去怎么办?

Jenkins在第一次进行登录的时候&#xff0c;只需要输入Jenkins\secrets\initialAdminPassword中的密码&#xff0c;登录成功后&#xff0c;本次我们没有修改密码&#xff0c;就会导致后面第二次登录&#xff0c;Jenkins需要进行用户名和密码的验证&#xff0c;但是我们根本就没…