Lambda 表达式
谓词函数: 进行一个操作时的一个临时函数,一般使用匿名函数。比如sort
函数的第三个参数即传入一个谓词函数
1 | std::sort(X, X+N, [](float a, float b) {return std::abs(a) < std::abs(b);}); |
Lambda 表达式使用一对方括号作为开始的标识,就类似于声明一个函数(也是匿名函数)
1 | std::cout<<[](float f) {return std::abs(f);}(-3.5); // 3.5 |
当只有一个返回值时,C++会自动判断返回值的类型而无需声明返回值的类型
我们也可以强制将返回值转换为int
1 | std::cout<<[](float f) -> int {return std::abs(f);}(-3.5); // 3 |
有点 JavaScript 里立即执行函数的味道了
我们可以使用auto
关键字来引入Lambda表达式
1 | auto lambda =[]() -> int {return val*100;}; |
auto
关键字将Lambda表达式转换成一种类似于std::function
的内部类型
1 | std::function<int()> lambda = []() -> int {return val*100}; |
当需要接受一个double
作为参数,返回int
的对象时
1 | std::function<int(double)> |
Lambda 引入符
Lambda 表达式前面的方括号[]
称为Lambda引入符
,它表示其后的 Lambda 表达式以何种方式捕获变量
[=] 以传值的方式捕获
1
2float f0 = 1.0;
std::cout<<[=](float f) {return f0 + std::abs(f);}(-3.5); // 4.5[&] 以传引用的方式捕获
1
std::cout << [&](float f) {return f0 += std::abs(f);}(-3.5); // 4.5
传值的捕获方式不允许修改外部变量,可以使用 mutabe
关键字调和(不报错,但还是不允许修改)
1 | float f0 = 1.0; |
可以将传值与传引用的机制相混合:比如f0通过引用捕获,f1通过传值捕获
1 | float f0 = 1.0f; |
总结
[]
不捕获任何外部变量[=]
以值的形式捕获所有外部变量[&]
以引用的形式捕获所有外部变量[x, &y]
x 以传值的形式捕获, y 以传引用的形式捕获[=, &z]
z 以传引用的形式捕获,其他变量则以传值的形式捕获[&, x]
x 以传值的形式捕获,其他变量则以传引用的形式捕获
最后,Lambda
表达式中可以直接使用 this
指针,但对[]
而言则需要显式传入:
1 | [this]() {this -> someFunc();}(); |