干啥的
C++ lambda表达式是一种匿名函数,它可以在需要函数对象的地方使用,而不需要显式地定义一个函数。
语法
[capture] (params) opt -> ret { body; }
[捕获列表](参数)mutable(可选)异常属性(可选)->返回类型{函数体}
示例
std::function<int(double)> func = [](double x)->int{ return round(x); }
std::cout << func(1.3) << endl;
捕获列表
lambda表达式的捕获列表用于指定在lambda函数体中可以访问的外部变量。捕获列表可以为空,也可以包含一个或多个捕获项,每个捕获项可以是变量、引用或者this指针。
捕获列表有以下几种形式:
- 值捕获(value capture):通过值捕获,lambda表达式会在创建时拷贝外部变量的值,并在函数体中使用该拷贝。捕获列表使用方括号[]表示,后面跟着要捕获的变量名。例如:[x, y]表示值捕获变量x和y。
- 引用捕获(reference capture):通过引用捕获,lambda表达式会在创建时绑定到外部变量的引用,并在函数体中使用该引用。捕获列表使用方括号[]表示,后面跟着要捕获的变量名前加上&符号。例如:[&x, &y]表示引用捕获变量x和y。
- 隐式捕获(implicit capture):通过隐式捕获,lambda表达式会根据使用的外部变量自动推断捕获方式。捕获列表使用方括号[]表示,但不指定具体的变量名。例如:[=]表示值捕获所有外部变量,[&]表示引用捕获所有外部变量。
- this指针捕获:通过this指针捕获,lambda表达式可以访问当前对象的成员变量。捕获列表使用方括号[]表示,后面跟着this关键字。例如:[this]表示通过值捕获当前对象的指针。
捕获列表中的变量可以在lambda函数体中使用,但不能修改(除非使用mutable关键字)。捕获列表的选择取决于外部变量的生命周期和使用方式,需要根据具体情况进行选择。
代码示例
#include <iostream>
class Example {
public:
Example(int x) : x(x) {}
void lambdaExample() {
int y = 10;
int z = 20;
// 值捕获x,引用捕获y,隐式捕获z
auto lambda = [&y, z, this]() mutable {
std::cout << "x: " << x << std::endl;
std::cout << "y: " << y << std::endl;
std::cout << "z: " << z << std::endl;
std::cout << "a: " << a << std::endl;
x++; // 值捕获的变量可以修改,需要使用mutable关键字
y++;
// z++; // 隐式捕获的变量不能修改
a++;
};
lambda();
std::cout << "x after lambda: " << x << std::endl;
std::cout << "y after lambda: " << y << std::endl;
std::cout << "z after lambda: " << z << std::endl;
std::cout << "a after lambda: " << a << std::endl;
}
private:
int x;
int a = 100;
};
int main() {
Example example(5);
example.lambdaExample();
return 0;
}
/**
x: 5
y: 10
z: 20
a: 100
x after lambda: 6
y after lambda: 11
z after lambda: 20
a after lambda: 101
**/
在上述示例中,lambda表达式中的捕获列表包含了部分捕获形式。值捕获了外部变量x,引用捕获了外部变量y,this指针捕获了成员变量a和变量x。lambda函数体中打印了捕获的变量,并对值捕获的变量进行了修改(需要使用mutable关键字)。在lambda函数执行后,可以看到外部变量z的值没有改变,而成员变量x,y,a的值增加了。