• 聊聊 C++ 和 C# 中的 lambda 玩法


    🚀 优质资源分享 🚀

    学习路线指引(点击解锁)知识定位人群定位
    🧡 Python实战微信订餐小程序 🧡进阶级本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。
    💛Python量化交易实战💛入门级手把手带你打造一个易扩展、更安全、效率更高的量化交易系统

    这几天在看 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;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    上面就定义了一个原子化的 lambda 函数,在现实开发中往往不仅要获取参数,还要获取 外部作用域 的变量,比如说,我想计算 a+b+c 的结果,接下来稍微改一下代码:

    可以看到,居然给报错了,在 C# 中可是一点问题都没有。

    1. 谨慎1 :屏蔽外部所有作用域变量

    C++ 默认屏蔽所有的外部作用域值,这么做大概率还是想让程序员知道自己的意图,这相比 C# 要严谨的多,算是喜忧参半吧。

    那如何让 C++ 代码通过呢? 这就需要用到语法格式中的 [capture] 部分,简而言之就是需要告诉编译器打开栅栏放哪些变量进来😄😄😄,比如 =,&,两者都可以访问所有的外部作用域变量,不同的是前者是 按传值方式,后者 按引用方式

    1. 按值方式

    有了思路后,修改代码如下:

    
    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;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    哈哈,这个问题我们完美搞定。

    1. 按引用方式

    大家都知道,按引用 传的是地址,言外之意就是可以做到 原地修改,接下来我们修改下代码。

    
    int main() {
    
    	int a = 1;
    
    	auto func1 = [&]() -> void {
    
    		a = 10;
    	};
    
    	func1();
    
    	cout << "a =" << a << endl;
    
    	return 0;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    谨慎2:屏蔽所有按值传递的修改

    为了方便说明,我们先看图:

    可以看到,按值传递进来的值都是无法修改的,这么做主要还是怕程序员弄混了,如果一定要让代码通过,就需要增加语法格式中的 mutable 项,本质上就是踢掉默认的 const ,这样在方法体中就可以修改 a 变量,修改代码如下:

    
    int main() {
    
    	int a = 1;
    
    	auto func1 = [=]() mutable -> void {
    
    		a = 10;
    	};
    
    	func1();
    
    	cout << "a =" << a << endl;
    
    	return 0;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    哈哈,成功修改,当然语句够简单的话,还可以将下面的代码:

    
    	auto func1 = [&]() -> void {
    
    		a = 10;
    	};
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    修改成如下:

    
    	auto func1 = [&]() {
    
    		a = 10;
    	};
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    关于作用域方面还有很多好玩的,比如只放某一个变量进来。

    总体上来说,C++ 的 lambda 的格式相比 C# 更严谨,反过来说就是不太相信 C++ 程序员有能力用好。😂😂😂,好了,本篇就聊这么多,希望对你有帮助。

  • 相关阅读:
    前端根据后端返回的数组对象处理转为树状结构
    Qt篇——QTableWidget选中多行右键删除
    BP神经网络需要训练的参数,BP神经网络图像识别
    MySQL执行计划
    Android中 BufferQueue 和 Gralloc
    Harmonic Drive哈默纳科减速机旋转方向和减速比
    电脑如何截屏?一起来揭晓答案!
    第4章 前馈神经网络
    什么是单子?Java 开发人员的基本理论
    uniapp 底部导航 点击刷新当前页
  • 原文地址:https://blog.csdn.net/www_xuhss_com/article/details/125289296