1.基本使用
Lambda函数也就是一个函数,它的语法定义如下:
[捕获列表](参数列表) mutable ->返回类型{函数体}
捕获列表 允许访问当前作用域下的某一个变量,可以为空(方括号不能省略)
参数列表 Lambda表达式的参数,可以省略(包括括号),不能有不定参数,不能有默认参数,参数必须有名称
mutable 捕获列表中的变量默认以const方式传递,不能修改,添加此关键字能指定变量可以被修改
类型 指定返回值类型(如果返回类型比较明显,可以省略,让编译器自动推断,省略时要连同->符号一起省略),包括void类型
函数体 需执行的代码,如果没有return语句且没指定类型,默认返回类型为void
捕获列表的说明如下
捕获形式 捕获类型 说明
[] 不捕获 不捕获外部变量
[变量名, …] 显式捕获 默认以值得形式捕获指定的多个外部变量(用逗号分隔),如果引用捕获,需要显示声明(使用&说明符)
[this] 显式捕获 以值的形式捕获this指针
[=] 隐式捕获 以值的形式捕获所有外部变量
[&] 隐式捕获 以引用形式捕获所有外部变量
[=, &x] 混合捕获 变量x以引用形式捕获,其余变量以传值形式捕获(注意顺序不能变,=符号一定要在前面)
[&, x] 混合捕获 变量x以值的形式捕获,其余变量以引用形式捕获(注意顺序不能变,&符号一定要在前面)
#include <iostream>
#include <string>
#include <stdio.h>
int main(int argc, char* argv[])
{
int a = 10, b = -1;
// 显式捕获,是以const方式传递,无法改变捕获值
auto f1 = [a, b]{ std::cout<<"f1 "<<"a:"<<a<<" b:"<<b<<std::endl;std::cout.flush();};
f1();
// 显式的值捕获,正常,注意此时()一定要加,不然依旧给你报错,
auto f2 = [a, b]()mutable{ a = 100; b = -10;std::cout<<"in f2 "<<"a:"<<a<<" b:"<<b<<std::endl;std::cout.flush();};
f2();
//修改的捕获值值,表达式外捕获值还是原值
std::cout<<"after f2 "<<"a:"<<a<<" b:"<<b<<std::endl;std::cout.flush();
// 显式的引用捕获
auto f3 = [&a, &b]{ a = 200; b = -20; std::cout<<"in f3 "<<"a:"<<a<<" b:"<<b<<std::endl;std::cout.flush();};
f3();
std::cout<<"after f3 "<<"a:"<<a<<" b:"<<b<<std::endl;std::cout.flush();
// 隐式的值捕获,报错,无法改变捕获值
//auto f4 = [=]{ a = 100; b = -10; };
// 隐式的值捕获,正常
auto f5 = [=]()mutable{ a = 300; b = -30; std::cout<<"in f5 "<<"a:"<<a<<" b:"<<b<<std::endl;std::cout.flush();};
f5();
std::cout<<"after f5 "<<"a:"<<a<<" b:"<<b<<std::endl;std::cout.flush();
// 隐式的引用捕获,正常
auto f6 = [&]{ a = 400; b = -40;std::cout<<"in f6 "<<"a:"<<a<<" b:"<<b<<std::endl;std::cout.flush(); };
f6();
std::cout<<"after f6 "<<"a:"<<a<<" b:"<<b<<std::endl;std::cout.flush();
// 混合捕获
auto f7 = [=, &a]{ a = 500;std::cout<<"in f7 "<<"a:"<<a<<std::endl;std::cout.flush(); };
f7();
std::cout<<"after f7 "<<"a:"<<a<<std::endl;std::cout.flush();
// 混合捕获,a是值传递,需要加mutable
//auto f8 = [&, a]{ a = 100; };
// 混合捕获,表达式外捕获值还是原值
auto f9 = [&, a]()mutable{ a = 600; std::cout<<"in f9 "<<"a:"<<a<<std::endl;std::cout.flush(); };
f9();
std::cout<<"after f9 "<<"a:"<<a<<std::endl;std::cout.flush();
}
使用lambda表达式时间有些需要主义的问题,
int j = 10;
auto by_val_lambda = [=]{ return j + 1; }; //返回值 11
auto by_ref_lambda = [&]{ return j + 1; };//返回值 11
std::cout<<"by_val_lambda: "<<by_val_lambda()<<std::endl;//输出11
std::cout<<"by_ref_lambda: "<<by_ref_lambda()<<std::endl;//输出11
j=12;
std::cout<<"by_val_lambda: "<<by_val_lambda()<<std::endl;//输出11
std::cout<<"by_ref_lambda: "<<by_ref_lambda()<<std::endl;//输出13
捕获值得的捕获方法,值按常量传递进来,不会随着包含lambda表达式函数中的赋值而改变。
2.stl与lambda表达式组合使用
#include <vector>
#include <iostream>
int main(int argc, char *argv[])
{
std::vector <int> v={1,2,3,4,5,6,7};
int count1=0;
std::for_each(v.begin(),v.end(),[&count1](int value){if(value>2){++count1;}});
std::cout<<"count1:"<<count1<<std::endl;
int count2=std::count_if(v.begin(),v.end(),[](int value){return value>2;});
std::cout<<"count2:"<<count2<<std::endl;
}