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.mzph.cn/bicheng/69968.shtml

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

相关文章

DeepSeek回答禅宗三重境界重构交易认知

人都是活在各自心境里&#xff0c;有些话通过语言去交流&#xff0c;还是要回归自己心境内在的&#xff0c;而不是靠外在映射到股票和技术方法&#xff1b;比如说明天市场阶段是不修复不接力节点&#xff0c;这就是最高视角看整个市场&#xff0c;还有哪一句话能概括&#xff1…

数据结构【链栈】

基于 C 实现链表栈&#xff1a;原理、代码与应用 一、引言 栈就是一个容器&#xff0c;可以当场一个盒子&#xff0c;只能一个一个拿&#xff0c;一个一个放&#xff0c;而且是从上面放入。 有序顺序栈操作比较容易【会了链栈之后顺序栈自然明白】&#xff0c;所以我们这里只…

成绩案例demo

本案例较为简单&#xff0c;用到的知识有 v-model、v-if、v-else、指令修饰符.prevent .number .trim等、computed计算属性、toFixed方法、reduce数组方法。 涉及的功能需求有&#xff1a;渲染、添加、删除、修改、统计总分&#xff0c;求平均分等。 需求效果如下&#xff1a…

C++:抽象类习题

题目内容&#xff1a; 求正方体、球、圆柱的表面积&#xff0c;抽象出一个公共的基类Container为抽象类&#xff0c;在其中定义一个公共的数据成员radius(此数据可以作为正方形的边长、球的半径、圆柱体底面圆半径)&#xff0c;以及求表面积的纯虚函数area()。由此抽象类派生出…

Java面试题2025-并发编程基础(多线程、锁、阻塞队列)

并发编程 一、线程的基础概念 一、基础概念 1.1 进程与线程A 什么是进程&#xff1f; 进程是指运行中的程序。 比如我们使用钉钉&#xff0c;浏览器&#xff0c;需要启动这个程序&#xff0c;操作系统会给这个程序分配一定的资源&#xff08;占用内存资源&#xff09;。 …

AI智慧社区--百度地图

数据库&#xff1a; 前端实现 页面代码 <template><div class"app-container"><baidu-map class"bm-view" :center"center" :zoom"zoom" ready"initMap"><!-- 定位 --><bm-geolocation anchor…

WSL2中安装的ubuntu搭建tftp服务器uboot通过tftp下载

Windows中安装wsl2&#xff0c;wsl2里安装ubuntu。 1. Wsl启动后 1&#xff09;Windows下ip ipconfig 以太网适配器 vEthernet (WSL (Hyper-V firewall)): 连接特定的 DNS 后缀 . . . . . . . : IPv4 地址 . . . . . . . . . . . . : 172.19.32.1 子网掩码 . . . . . . . .…

一、TensorFlow的建模流程

1. 数据准备与预处理&#xff1a; 加载数据&#xff1a;使用内置数据集或自定义数据。 预处理&#xff1a;归一化、调整维度、数据增强。 划分数据集&#xff1a;训练集、验证集、测试集。 转换为Dataset对象&#xff1a;利用tf.data优化数据流水线。 import tensorflow a…

软件工程概论试题五

一、多选 1.好的软件的基本属性包括()。 A. 效率 B. 可依赖性和信息安全性 C. 可维护性 D.可接受性 正答&#xff1a;ABCD 2.软件工程的三要素是什么()? A. 结构化 B. 工具 C.面向对象 D.数据流! E.方法 F.过程 正答&#xff1a;BEF 3.下面中英文术语对照哪些是正确的、且是属…

问题的价值 ( Value of Question ) 公式

一、什么是问题的价值 我们的人生、工作的期间、瞬息万变的商业环境中&#xff0c;我们必然会面对很多问题&#xff0c;也会提出很多问题。 但这些问题是否具有回答的 价值&#xff0c;应该如何 衡量 呢&#xff1f; 简单如&#xff0c;女朋友问今晚应该吃什么、世界如何才能…

一文了解阿里的 Qwen2.5 模型

最近被DeepSeek刷屏了&#xff0c;但是在之外阿里在2025年1月28日推出了Qwen 2.5 Max模型。 Qwen2.5-Max 的特点&#xff1a;大规模的 MoE 模型&#xff0c;预训练于超 20 万亿 tokens&#xff0c;并经过 SFT 和 RLHF 后训练。 性能表现&#xff1a;在多个基准测试中与领先模型…

基于Django的Boss直聘IT岗位可视化分析系统的设计与实现

【Django】基于Django的Boss直聘IT岗位可视化分析系统的设计与实现&#xff08;完整系统源码开发笔记详细部署教程&#xff09;✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 该系统采用Python作为主要开发语言&#xff0c;利用Django这一高效、安全的W…

Hive:复杂数据类型之Map函数

Map函数 是Hive里面的一种复杂数据类型, 用于存储键值对集合。Map中的键和值可以是基础类型或复合类型&#xff0c;这使得Map在处理需要关联存储信息的数据时非常有用。 定义map时,需声明2个属性: key 和 value , map中是 key value 组成一个元素 key-value, key必须为原始类…

计算机毕业设计Python动漫推荐系统 漫画推荐系统 动漫视频推荐系统 机器学习 bilibili动漫爬虫 数据可视化 数据分析 大数据毕业设计

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

2025年02月02日Github流行趋势

项目名称&#xff1a;oumi 项目地址url&#xff1a;https://github.com/oumi-ai/oumi 项目语言&#xff1a;Python 历史star数&#xff1a;1416 今日star数&#xff1a;205 项目维护者&#xff1a;xrdaukar, oelachqar, taenin, wizeng23, kaisopos 项目简介&#xff1a;构建最…

谭浩强C语言程序设计(3) 7章

1、递归实现N的阶乘 c复制 #include <cstdio> // 包含标准输入输出库// 计算n的阶乘 int total 0; // 定义全局变量total用于存储阶乘结果// 递归函数计算阶乘 int fac(int a){// 如果输入的数小于0&#xff0c;输出错误信息if (a < 0){printf("%d < 0,err…

python算法和数据结构刷题[2]:链表、队列、栈

链表 链表的节点定义&#xff1a; class Node():def __init__(self,item,nextNone):self.itemitemself.nextNone 删除节点&#xff1a; 删除节点前的节点的next指针指向删除节点的后一个节点 添加节点&#xff1a; 单链表 class Node():"""单链表的结点&quo…

网络工程师 (13)时间管理

一、定义与重要性 项目时间管理是指为确保项目按时完成而采取的一系列规划、安排和控制活动。它始于项目启动阶段&#xff0c;贯穿整个项目生命周期&#xff0c;直至项目结束。时间管理对于项目的成功至关重要&#xff0c;它有助于项目团队明确工作目标和时间节点&#xff0c;增…

2025.2.1——四、php_rce RCE漏洞|PHP框架

题目来源&#xff1a;攻防世界 php_rce 目录 一、打开靶机&#xff0c;整理信息 二、解题思路 step 1&#xff1a;PHP框架漏洞以及RCE漏洞信息 1.PHP常用框架 2.RCE远程命令执行 step 2&#xff1a;根据靶机提示&#xff0c;寻找版本漏洞 step 3&#xff1a;进行攻击…

记录 | 基于MaxKB的文字生成视频

目录 前言一、安装SDK二、创建视频函数库三、调试更新时间 前言 参考文章&#xff1a;如何利用智谱全模态免费模型&#xff0c;生成大家都喜欢的图、文、视并茂的文章&#xff01; 自己的感想 本文记录了创建文字生成视频的函数库的过程。如果想复现本文&#xff0c;需要你逐一…