C++ lambda表达式,又称为闭包,匿名函数
入门语法
举个例子
auto f = [](int a,int b){
return a <b;
};
std::vector<int> vec = {0,11,2,23,4};
std::sort(vec.begin(),vec.end(),f);
上面的就是通过一个简单的匿名函数来简化了排序,lambda表达式具体语法如下:
[OuterVar](int x,int y)->int {
return OuterVar + x+y;
}
其中[]中OuterVar被称为捕获变量,可以有值或者为空,然后括号中包起来的是参数列表,箭头跟着返回类型,最后是函数体。其他lambda表达式的返回类型,编译器会自行推导,所以上面的代码中的->可以省略。下面和上面是等价的。
[OuterVar](int x,int y){
return OuterVar + x+y;
}
变量的捕获(capture clause)
介绍捕获
让我们的匿名函数可以访问外部变量,甚至修改外部变量
举例
int N=100,M=10;
auto g = [N,&M](int i)
{
M=20;
return N*i;
};
std::cout<<g(10) <<" "<<M<<std::endl;
//输出 1000 20
这里的N和M都被匿名函数访问了,M前有引用符号,表示按照引用来捕获。
[&]和[=] 捕获
[&]和[=]是两种常见的捕获模式,它们分别代表按引用捕获和按值捕获。
[&]:按引用捕获
使用&符号表示lambda表达式应该按引用捕获其封闭作用域中的所有变量。这意味着在lambda函数体内对捕获的变量的任何修改都会影响到原始变量。
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5};
// 使用lambda表达式按引用捕获变量sum,并在lambda中修改它
int sum = 0;
std::for_each(numbers.begin(), numbers.end(), [&sum](int n) {
sum += n;
});
std::cout << "Sum: " << sum << std::endl; // 输出:Sum: 15
return 0;
}
//输出 Sum: 15
[=]:按值捕获
使用=符号表示lambda表达式应该按值捕获其封闭作用域中的所有变量。这意味着在lambda函数体内捕获的变量是原始变量的副本,对副本的任何修改都不会影响到原始变量。
注意不能对其中变量进行修改。
#include <iostream>
int main() {
int x = 10;
int y = 20;
// 使用[=]按值捕获x和y
auto lambda = [=]() {
std::cout << "x = " << x << ", y = " << y << std::endl;
// 注意:不能修改x和y,因为它们是按值捕获的副本
// x=20; 这个代码编译器会报错
};
// 调用lambda表达式
lambda();
return 0;
}
其他捕获的知识
[this] 表示捕获当前实例的指针
[*this] 表示按值捕获该实例
在C++14后,你还可以在捕获语句中定义新变量
#include <iostream>
int main() {
int x = 10;
int y = 20;
// 增加新变量k
auto lambda = [x,y,k=5]() {
std::cout << "x = " << x << ", y = " << y << ", k = " << k << std::endl;
// x = 10, y = 20, k = 5
};
lambda();
return 0;
}
在C++14后,lambda的参数列表支持auto类型,更加通用和泛化
int x = 10;
int y = 20;
// 参数列表修改成auto类型
auto lambda = [](auto x,auto y) {
std::cout << "x = " << x << ", y = " << y << std::endl;
// x = 10, y = 20, k = 5
};
lambda(x,y);
//输出 x = 10, y = 20
标签:std,变量,int,auto,捕获,C++,表达式,lambda
From: https://www.cnblogs.com/AndreaDO/p/18022779