高端知识点:折叠表达式(我也是第一次知道)
C语言题库
共 4185字,需浏览 9分钟
· 2021-07-17
The sports meet
跑得慢,会遭遇残酷,跑得快,才能遇到激荡
不知道大家以前了解折叠表达式不,这里介绍一下!
我也是最近才知道这个知识点,在C++中通过折叠表达式可以更容易的在可变参数模板中处理可变参数。
先看一下传统的使用递归方式来处理可变参数的代码:
void print(int i) {
std::cout << i << " ";
}
void func() {}
template<typename T1, typename... Tn>
void func(T1 arg1, Tn... args) {
print(arg1);
func(args...);
}
int main() {
func(2, 3, 4);
std::cout << "Hello World \n";
}
注意看代码里还需要有个不带参数的func()来停止递归。很麻烦!
而使用折叠表达式,通过单个函数模板就可以实现上述功能,不需要多余的函数,看代码:
void print(int i) {
std::cout << i << " ";
}
template<typename... T>
void func(const T&... args) {
(print(args), ...);
std::cout << "\n";
}
int main() {
func(1, 2, 3);
std::cout << "Hello World \n";
}
函数体中的三个点触发折叠。它会针对可变参数中的每个参数调用print(),对print()的每个调用用逗号分隔。
例如对于func(1, 2, 3),函数内的折叠表达式会展开成这样:
(print(1), (print(2), print(3)));
再用一个例子巩固下:
template<typename... T>
void func(const T&... args) {
((std::cout << args << " "), ...);
std::cout << "\n";
}
int main() {
func(1, 2, 3);
std::cout << "Hello World \n";
}
下面是折叠表达式展开后的形式:
((std::cout << 1<< " "), ((std::cout << 2 << " "), (std::cout << 3 << " ")));
上面的示例中都是与逗号运算符结合使用,但实际上折叠可以和任何类型的运算符结合使用。例如与加号结合使用来计算所有值的和:
template<typename T, typename... Tn>
int sum(const T& v, const Tn&... values) {
return (v + ... + values);
}
template<typename... Tn>
int sum2(const Tn&... values) {
return (... + values);
}
int main() {
std::cout << sum(1, 2, 3, 4) << "\n";
std::cout << sum2(1, 2, 3, 4) << "\n";
std::cout << "Hello World \n";
}
对于sum(1, 2, 3, 4),展开的形式如下:
return (((1 + 2) + 3) + 4);
但这里有个问题,该函数的使用一定需要至少一个参数,否则将无法通过编译:
template<typename T, typename... Tn>
int sum(const T& v, const Tn&... values) {
return (v + ... + values);
}
int main() {
sum();
std::cout << "Hello World \n";
}
报错如图:
长度为0其实也可以使用折叠表达式,但不能和加减这种运算符结合使用,只能和逻辑与、逻辑或和逗号结合使用。例如:
template <typename... Values>
double allTrue(const Values&... values) {
return (... && values);
}
template <typename... Values>
double anyTrue(const Values&... values) {
return (... || values);
}
int main() {
std::cout << allTrue(1, 1, 0) << allTrue(1, 1) << allTrue() << "\n"; // 011
std::cout << anyTrue(1, 1, 0) << anyTrue(0, 0) << anyTrue() << "\n"; // 100
}
关于折叠表达式的介绍就到这里,打完收工!希望对大家有所帮助!
参考资料:
《Professional C++》
评论
我看阿里的年终奖总算发了!
到4月底了,这两天看朋友圈,发现阿里的年终奖终于发了,问了问老同学,也从网上检索了不少信息,基本搞清楚了阿里今年的年终奖情况。近来来阿里一些集团对绩效等级做了较大的调整,以前的旧绩效系统中,绩效分为3.25、3.5、3.75、4和5五个等级,其中4和5是较高绩效等级,较少见。而且之前3.5绩效内部划
公子龙
0
老爸嘲讽我了,写破代码一年就挣十几万,他在工地带50个工人,一个月光人头费就3万,让我滚回去跟他干!
点击上方 "大数据肌肉猿"关注, 星标一起成长点击下方链接,进入高质量学习交流群今日更新| 1052个转型案例分享-大数据交流群来自:网络,侵删有个网友的父亲是做工程的,天天就嘲笑他,说他天天写着破代码有啥用,一年就拿个十多万的死工资,然后告诉他自己在工地里面带了50个工人,一个月能抽三万
程序源代码
0
我发现 Lombok的几个骚操作,哈哈好用
大家好,我是小富~前言本文不讨论对错,只讲骚操作。有的方法看看就好,知道可以这么用,但是否应用到实际开发中,那就仁者见仁,智者见智了。一万个读者就会有一万个哈姆雷特,希望这篇文章能够给您带来一些思考。耐心看完,你一定会有所收获。@onX例如 onConstructor, oMet
程序员内点事
0
聊一聊我最常关注的9个计算机视觉、自动驾驶、AI方向高质量圈子
随着计算机视觉(2D/3D)、SLAM、自动驾驶、AI技术的快速迭代更新,可落地的技术也成为人们争先学习的重点。这使得从业者对于最前沿技术的获取能力变得至关重要。微信公众号便是一个非常有效的前沿信息分享平台。这里给大家推荐9个最常打开的计算机视觉、自动驾驶、SLAM、机器学习和AI方向的优质公众号平
机器学习初学者
0
我想写几个专栏,欢迎大家投票
大家好,我是章北海前段时间更新了一个专栏,阅读和订阅都极不理想,看起来是没有做好调研啊。准备启动新的专栏更新计划了,我有几个选题,看大家更喜欢哪一个呢?欢迎投票,拜谢!
机器学习算法与Python实战
0
聊一聊我最关注的9个CV、SLAM、自动驾驶和AI圈子!
随着计算机视觉(2D/3D)、SLAM、自动驾驶、AI技术的快速迭代更新,可落地的技术也成为人们争先学习的重点。这使得从业者对于最前沿技术的获取能力变得至关重要。微信公众号便是一个非常有效的前沿信息分享平台。这里给大家推荐9个最常打开的计算机视觉、自动驾驶、SLAM、机器学习和AI方向的优质公众号平
3D视觉工坊
0
我发现这款浏览器真不错
“软件分享”只分享好玩有趣的黑科技软件很多人都知道我的电脑安装了10款浏览器,每一款浏览器都有自己的分工,国内外的浏览器基本都用过,今天我又发现了一款浏览器。下载用了一下午感觉还很符合国内用户使用,这款浏览器叫CentBrowser(百分浏览器)。可以说是谷歌浏览器增强版吧。Cent Browser
一锅汤软件
2
35K*14 薪入职了,这公司只要不裁员,我能一直呆下去。。
大家好,我是R哥。说说最近的面试辅导,有个学员进了某个知名互联网公司,拿到了 35K*14 薪的好成绩,有不少粉丝留言问我,现在行情这么差,他是怎么做到的?这篇拿他这个案例完整回顾一下吧,我管他叫小Y吧。背景沟通说下小Y的基本情况吧:小Y工作 5 年+,空窗期2个月+,5 年干了 3 家单位,学历不
Java技术栈
0