5

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

 1 year ago
source link: https://www.cnblogs.com/huangxincheng/p/16375699.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

这几天在看 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;
}

851ec3a22fe445d98a11b4a25aa45477~tplv-k3u1fbpfcp-zoom-1.image

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

d6a2e13142054d06864dc8e08794ba7a~tplv-k3u1fbpfcp-zoom-1.image

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

175772a7633b4b2d82f80764f6513a9e~tplv-k3u1fbpfcp-zoom-1.image

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;
}

5d5b8c7e759f433fad9f317c71dd4a4b~tplv-k3u1fbpfcp-zoom-1.image

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

  1. 按引用方式

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


int main() {

	int a = 1;

	auto func1 = [&]() -> void {

		a = 10;
	};

	func1();

	cout << "a =" << a << endl;

	return 0;
}

48ba579f4eae483894494c89cfca7568~tplv-k3u1fbpfcp-zoom-1.image

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

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

2cc1be3babf34dc49c025c80cc386221~tplv-k3u1fbpfcp-zoom-1.image

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


int main() {

	int a = 1;

	auto func1 = [=]() mutable -> void {

		a = 10;
	};

	func1();

	cout << "a =" << a << endl;

	return 0;
}

a4a2b50668c34bef96855c1060dd1d1c~tplv-k3u1fbpfcp-zoom-1.image

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


	auto func1 = [&]() -> void {

		a = 10;
	};

修改成如下:


	auto func1 = [&]() {

		a = 10;
	};

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

015e3e440e9c4342a6eaea563a0d9088~tplv-k3u1fbpfcp-zoom-1.image

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

图片名称

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK