干啥的
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的值增加了。