概述
C++ lambda表达式的本质就是重载了 operator(),lambda是一个类,在调用时会进行编译展开。因此lambda表达式对象其实就是一个匿名的functor,所以 lambda 表达式 也叫匿名函数对象。
C++中lambda表达式的构成
一个标准的lambda表达式包括:捕获列表、参数列表、mutable指示符、异常列表、返回类型(->返回类型)和函数体:
[捕获列表] (形参列表) mutable 异常列表-> 返回类型
{
函数体
}
各项的含义:
-
捕获列表:捕获外部变量,捕获的变量可以在函数体中使用,可以省略,即不捕获外部变量。
-
形参列表:和普通函数的形参列表一样。可省略,即无参数列表
-
mutable:mutable 关键字,如果有,则表示在函数体中可以修改捕获变量,根据具体需求决定是否需要省略。
-
异常列表:noexcept / throw(...),和普通函数的异常列表一样,可省略,即代表可能抛出任何类型的异常。
-
返回类型:和函数的返回类型一样。可省略,如省略,编译器将自动推导返回类型。
-
函数体:代码实现。可省略,但是没意义。
捕获列表
由于lambda表达式是在某函数内定义的,因此我们可能希望其能使用函数内的局部变量,这时则可以使用所谓捕获列表。总体说来,一共有三种捕获方式:值捕获、引用捕获和外部捕获。
值捕获
值捕获和参数传递中的值传递类似,被捕获的变量的值在Lambda表达式创建时通过值拷贝的方式传入,因此随后对该变量的修改不会影响影响Lambda表达式中的值。注意,不能在lambda表达式中修改捕获变量的值。代码如下:
#include <iostream>
using namespace std;
int main()
{
int nCapture = 13;
auto f = [nCapture](int a, int b) -> int
{
//nCapture = 134; //不能在lambda表达式中修改捕获变量的值
return a + b + nCapture;
};
cout << f(4, 3) << endl;
cout << "nCapture=" << nCapture << endl;
return 0;
}
引用捕获
使用引用捕获一个外部变量,需在捕获列表变量前面加上一个引用说明符&。如下:
#include <iostream>
using namespace std;
int main()
{
int nCapture = 13;
auto f = [&nCapture](int a, int b) -> int
{
cout << "In functor before change nCapture=" << nCapture << endl; //在调用lamd之前 nCapture = 12345
nCapture = 134;
cout << "In functor after change nCapture=" << nCapture << endl; // nCapture = 134
return a + b + nCapture;
};
nCapture = 12345;
cout << f(4, 3) << endl;
cout << "nCapture=" << nCapture << endl; //经过了lambda计算后,nCapture值变为修改后的134
return 0;
}
代码结果:
In functor before change nCapture=12345
In functor after change nCapture=134
141
nCapture=134
根据以上说明,引用捕获,可以在lambda函数体修改捕获的值。
隐式捕获
上面的值捕获和引用捕获都需要我们在捕获列表中显示列出Lambda表达式中使用的外部变量。除此之外,我们还可以让编译器根据函数体中的代码来推断需要捕获哪些变量,这种方式称之为隐式捕获。隐式捕获有两种方式,分别是[=]和[&]。[=]表示以值捕获的方式捕获外部变量,[&]表示以引用捕获的方式捕获外部变量。
lambda表达式的应用场景:
(1)Qt信号槽,槽函数可以用lambda表达式来写;
(2)线程代码
下面是3种捕获方式的简要测试,代码如下:
/*
lambda变量捕获测试代码
[=] 表示按值捕获,不允许修改;x是只读,无法修改
[&] &表示引用捕获, 在lambda里可以修改捕获的值
mutable 使用 mutable 表示可以修改按值捕获的副本,并不修改原来的值
*/
#include <iostream>
using namespace std;
int main()
{
int x = 100;
int y = 123;
auto f1 = [=]() {
//x += 1; //= 表示按值捕获,不允许修改;x是只读,无法修改
};
auto f2 = [&]() {
x += 100; //正确,&表示引用捕获
};
auto f3 = [=, &x] {
//y += 100; //除了x之外,其它的都是按值捕获
x += 100;
};
f2();
f3();
cout << "x = " << x << endl;
auto f4 = [=]() mutable //使用 mutable 表示可以修改按值捕获的副本,并不修改原来的值
{
y += 100;
cout << "f4 y = " << y << endl;
};
f4();
cout << "y = " << y << endl;
return 0;
}
最后
以上就是哭泣羽毛为你收集整理的C++ lambda表达式用法说明的全部内容,希望文章能够帮你解决C++ lambda表达式用法说明所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复