欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C++ 11 Lambda表达式

程序员文章站 2022-05-22 21:21:42
...

C++11的一大亮点就是引入了Lambda表达式。利用Lambda表达式,可以方便的定义和创建匿名函数。

声明Lambda表达式

Lambda表达式完整的声明格式如下:

[capture list] (params list) mutable exception-> return type { function body }

各项具体含义如下

  1. capture list:捕获外部变量列表
  2. params list:形参列表
  3. mutable指示符:用来说用是否可以修改捕获的变量
  4. exception:异常设定
  5. return type:返回类型
  6. function body:函数体

此外,我们还可以省略其中的某些成分来声明“不完整”的Lambda表达式,常见的有以下几种:

序号 格式
1 [capture list] (params list) -> return type {function body}
2 [capture list] (params list) {function body}
3 [capture list] {function body}

例子:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

bool cmp(int a, int b) {
	return  a < b;
}

int main() {
	vector<int> myvec{ 3, 2, 5, 7, 3, 2 };
	vector<int> lbvec(myvec);

	sort(myvec.begin(), myvec.end(), cmp); // 旧式做法
	cout << "predicate function:" << endl;
	for (int it : myvec)
		cout << it << ' ';
	cout << endl;

	sort(lbvec.begin(), lbvec.end(), [](int a, int b) -> bool { return a < b; });   // Lambda表达式
	cout << "lambda expression:" << endl;
	for (int it : lbvec)
		cout << it << ' ';
	cout << endl;
	system("pause");
	return 0;
}

C++ 11 Lambda表达式

在C++11之前,我们使用STL的sort函数,需要提供一个谓词函数。如果使用C++11的Lambda表达式,我们只需要传入一个匿名函数即可,方便简洁,而且代码的可读性也比旧式的做法好多了。

 

捕获外部变量: 

值捕获

值捕获和参数传递中的值传递类似,被捕获的变量的值在Lambda表达式创建时通过值拷贝的方式传入,因此随后对该变量的修改不会影响影响Lambda表达式中的值。

#include <iostream>
using namespace std;

bool cmp(int a, int b) {
	return  a < b;
}

int main() {
	int a = 123;
	auto f = [a] {cout << a << endl; };
	a = 423;
	f();
	system("pause");
	return 0;
}

C++ 11 Lambda表达式

结果是123;并非423。

这里需要注意的是,如果以传值方式捕获外部变量,则在Lambda表达式函数体中不能修改该外部变量的值。

 

 

引用捕获

使用引用捕获一个外部变量,只需要在捕获列表变量前面加上一个引用说明符&。如下:

#include <iostream>
using namespace std;

bool cmp(int a, int b) {
	return  a < b;
}

int main() {
	int a = 123;
	auto f = [&a] { cout << a << endl; };
	a = 321;
	f(); // 输出:321
	system("pause");
	return 0;
}

C++ 11 Lambda表达式

从示例中可以看出,引用捕获的变量使用的实际上就是该引用所绑定的对象。

 

隐式捕获

上面的值捕获和引用捕获都需要我们在捕获列表中显示列出Lambda表达式中使用的外部变量。除此之外,我们还可以让编译器根据函数体中的代码来推断需要捕获哪些变量,这种方式称之为隐式捕获。隐式捕获有两种方式,分别是[=]和[&]。[=]表示以值捕获的方式捕获外部变量,[&]表示以引用捕获的方式捕获外部变量。

 

就是

将lambda表达式的    []     中  a    改为   =      为“隐式值捕获”

将lambda表达式的    []     中  &a    改为   &      为“隐式引用捕获”

例子就是上面的,结果都是一样的。

 

总结:

捕获形式 说明
[] 不捕获任何外部变量
[变量名, …] 默认以值得形式捕获指定的多个外部变量(用逗号分隔),如果引用捕获,需要显示声明(使用&说明符)
[this] 以值的形式捕获this指针
[=] 以值的形式捕获所有外部变量
[&] 以引用形式捕获所有外部变量
[=, &x] 变量x以引用形式捕获,其余变量以传值形式捕获
[&, x] 变量x以值的形式捕获,其余变量以引用形式捕获

 

 

相关标签: lambda