聊聊 C++ 和 C# 中的 lambda 玩法
这几天在看 C++ 的 lambda 表达式,挺有意思,这个标准是在 C11标准
加进去的,也就是 2011 年,相比 C# 2007 还晚了个 4 年, Lambda 这东西非常好用,会上瘾,今天我们简单聊一聊。
一:语法定义
首先我们看下 C++ 语法定义格式:
[capture] (parameters) mutable ->return-type{statement}
相比 C# lambda 的语法格式:
(parameters) => {return-type statement}
要复杂一些,之所以复杂还是因为 C++ 让程序员用的必须更谨慎一些。
二:谨慎在哪里?
为了说明更谨慎在哪里,我们上一个简单的例子。
int main() {
int a = 1;
int b = 2;
auto func = [](int c) -> void {
cout << "input:" << c << endl;
};
func(10);
return 0;
}
上面就定义了一个原子化的 lambda 函数,在现实开发中往往不仅要获取参数,还要获取 外部作用域
的变量,比如说,我想计算 a+b+c
的结果,接下来稍微改一下代码:
可以看到,居然给报错了,在 C# 中可是一点问题都没有。
1. 谨慎1 :屏蔽外部所有作用域变量
C++ 默认屏蔽所有的外部作用域值,这么做大概率还是想让程序员知道自己的意图,这相比 C# 要严谨的多,算是喜忧参半吧。
那如何让 C++ 代码通过呢? 这就需要用到语法格式中的 [capture]
部分,简而言之就是需要告诉编译器打开栅栏放哪些变量进来,比如 =,&
,两者都可以访问所有的外部作用域变量,不同的是前者是 按传值方式,后者 按引用方式 。
- 按值方式
有了思路后,修改代码如下:
int main() {
int a = 1;
int b = 2;
auto func = [=](int c) -> void {
auto sum = a + b + c;
cout << "sum:" << sum << endl;
};
func(10);
return 0;
}
哈哈,这个问题我们完美搞定。
- 按引用方式
大家都知道,按引用
传的是地址,言外之意就是可以做到 原地修改
,接下来我们修改下代码。
int main() {
int a = 1;
auto func1 = [&]() -> void {
a = 10;
};
func1();
cout << "a =" << a << endl;
return 0;
}
谨慎2:屏蔽所有按值传递的修改
为了方便说明,我们先看图:
可以看到,按值传递进来的值都是无法修改的,这么做主要还是怕程序员弄混了,如果一定要让代码通过,就需要增加语法格式中的 mutable
项,本质上就是踢掉默认的 const
,这样在方法体中就可以修改 a
变量,修改代码如下:
int main() {
int a = 1;
auto func1 = [=]() mutable -> void {
a = 10;
};
func1();
cout << "a =" << a << endl;
return 0;
}
哈哈,成功修改,当然语句够简单的话,还可以将下面的代码:
auto func1 = [&]() -> void {
a = 10;
};
修改成如下:
auto func1 = [&]() {
a = 10;
};
关于作用域方面还有很多好玩的,比如只放某一个变量进来。
总体上来说,C++ 的 lambda 的格式相比 C# 更严谨,反过来说就是不太相信 C++ 程序员有能力用好。,好了,本篇就聊这么多,希望对你有帮助。
聊聊 C++ 和 C# 中的 lambda 玩法的更多相关文章
- C#语法糖系列 —— 第二篇:聊聊 ref,in 修饰符底层玩法
自从 C# 7.3 放开 ref 之后,这玩法就太花哨了,也让 C# 这门语言变得越来越多范式,越来越重,这篇我们就来聊聊 ref,本质上来说 ref 的放开就是把 C/C++ 指针的那一套又拿回来了 ...
- javascript中的数字玩法,颠覆你的眼睛
1.JavaScript中的数字中有一些很奇葩的现象. 在Chrome控制台中可以自己做一下实验: 1 === 1.0 ; //true 习惯了强类型语言,如java,c,OC看到这个结论还是有点小迷 ...
- 性能计数器在.NET Core中的新玩法
传统的.NET Framework提供的System.Diagnostics.PerformanceCounter类型可以帮助我们收集Windows操作系统下物理机或者进程的性能指标,基于Perfor ...
- js中insertAdjacentHTML的玩法
原型:insertAdajcentHTML(swhere,stext) insertAdjacentHTML方法:在指定的地方插入html标签语句 参数:swhere: 指定插入html标签语句的地方 ...
- 聊聊 C# 和 C++ 中的 泛型模板 底层玩法
最近在看 C++ 的方法和类模板,我就在想 C# 中也是有这个概念的,不过叫法不一样,人家叫模板,我们叫泛型,哈哈,有点意思,这一篇我们来聊聊它们底层是怎么玩的? 一:C++ 中的模板玩法 毕竟 C+ ...
- C#语法糖系列 —— 第三篇:聊聊闭包的底层玩法
有朋友好奇为什么将 闭包 归于语法糖,这里简单声明下,C# 中的所有闭包最终都会归结于 类 和 方法,为什么这么说,因为 C# 的基因就已经决定了,如果大家了解 CLR 的话应该知道, C#中的类最终 ...
- [转]Pythoin中的Lambda表达式
引用自:http://www.cnblogs.com/evening/archive/2012/03/29/2423554.html 在学习python的过程中,lambda的语法时常会使人感到困惑, ...
- 【第1期】腾讯云的1001种玩法征集,Ipad mini和Kindle 等你拿!(文章评审中)
版权声明:本文由阁主的小跟班原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/695994001482226944 来源:腾云 ...
- 你知道C#中的Lambda表达式的演化过程吗
你知道C#中的Lambda表达式的演化过程吗? 阅读目录 委托的使用 匿名方法 Func和Action Lambda的诞生 那得从很久很久以前说起了,记得那个时候... 懵懂的记得从前有个叫委托的东西 ...
随机推荐
- Ubuntu16更换flatabulous主题
Ubuntu16更换flatabulous主题 安装unity-tweak-tool sudo apt-get install unity-tweak-tool 安装flatabulous主题 sud ...
- 百度离线人脸识别sdk的使用
1.1下载sdk运行 百度离线人脸识别sdk的使用 1.2配置环境 添加至项目,可以拖动复制或者以类库形式添加face-resource此文件夹 放到根目录上一层 激活文件与所有dll引用放到根目录嫌 ...
- mysql发展历程 各分支版本溯源
首先为什么要了解mysql的历史,了解一个软件的前生后世有时候还是很有必要,特别是对于走在架构之路或者是想深入了解一个软件的时候,在不同版本中由于进行了很多的改进或者说加入了新的功能,也有可能是软件本 ...
- 【LeetCode】358.K 距离间隔重排字符串
358.K 距离间隔重排字符串 知识点:哈希表:贪心:堆:队列 题目描述 给你一个非空的字符串 s 和一个整数 k,你要将这个字符串中的字母进行重新排列,使得重排后的字符串中相同字母的位置间隔距离至少 ...
- 如何让HTTPS站点评级达到A+? 还得看这篇HTTPS安全优化配置最佳实践指南
0x00 前言简述 SSL/TLS 简单说明 描述: 当下越来越多的网站管理员为企业站点或自己的站点进行了SSL/TLS配置, SSL/TLS 是一种简单易懂的技术,它很容易部署及运行,但要对其进行安 ...
- SpringMVC踩坑3——前后端传值问题
在前端页面点击修改,同时把需要修改的ID传到后端,后端根据ID去修改具体数据 这是前端代码 <a href="${pageContext.request.contextPath}/bo ...
- HCIE笔记-第一节-网络的基本概念
R&S= 路由交换 Datacom =数通 =数据通信 某个设备产生了数据之后,借助整体的网络到达目的地的过程. 网络历史 -- 数通为什么产生? 1946年:世界上第一台计算机诞生.军事 科 ...
- Java语言学习day21--7月27日
###01接口的概念 * A:接口的概念 接口是功能的集合,同样可看做是一种数据类型,是比抽象类更为抽象的"类". 接口只描述所应该具备的方法,并没有具体实现,具体的实现由接口的实 ...
- java中int的最值解析
java中int的最大值为十进制的2147483647,也就是java能进行操作的最大数值,超出就会显示不正常.针对以下问题进行讨论. 1.最大值为什么是2147483647? java中int类型占 ...
- 普罗米修斯!Ubuntu下prometheus监控软件安装使用
*Prometheus* 是一个开源的服务监控系统和时间序列数据库 官方网站:prometheus.io 一.安装prometheus cd /usr/local/ #进入安装目录 wg ...