基本语法
简单来说,Lambda函数也就是一个函数,它的语法定义如下:
capture mutable ->return-type{statement}
1.[capture]:捕捉列表。捕捉列表总是出现在Lambda函数的开始处。实际上,[]是Lambda引出符。编译器根据该引出符判断接下来的代码是否是Lambda函数。捕捉列表能够捕捉上下文中的变量以供Lambda函数使用;
2.(parameters):参数列表。与普通函数的参数列表一致。如果不需要参数传递,则可以连同括号“()”一起省略;
3.mutable:mutable修饰符。默认情况下,Lambda函数总是一个const函数,mutable可以取消其常量性。在使用该修饰符时,参数列表不可省略(即使参数为空);
4.->return-type:返回类型。用追踪返回类型形式声明函数的返回类型。我们可以在不需要返回值的时候也可以连同符号”->”一起省略。此外,在返回类型明确的情况下,也可以省略该部分,让编译器对返回类型进行推导;
5.{statement}:函数体。内容与普通函数一样,不过除了可以使用参数之外,还可以使用所有捕获的变量。
与普通函数最大的区别是,除了可以使用参数以外,Lambda函数还可以通过捕获列表访问一些上下文中的数据。具体地,捕捉列表描述了上下文中哪些数据可以被Lambda使用,以及使用方式(以值传递的方式或引用传递的方式)。语法上,在“[]”包括起来的是捕捉列表,捕捉列表由多个捕捉项组成,并以逗号分隔。捕捉列表有以下几种形式:
1.[var]表示值传递方式捕捉变量var;
2.[=]表示值传递方式捕捉所有父作用域的变量(包括this);
3.[&var]表示引用传递捕捉变量var;
4.[&]表示引用传递方式捕捉所有父作用域的变量(包括this);
5.[this]表示值传递方式捕捉当前的this指针。
下面介绍二个案例:
#include<iostream>
using namespace std;
typedef enum
{
add = 0,
sub,
mul,
divi
}type;
int main()
{
int a = 10;
int b = 20;
auto func = [=](type i)->int {
switch (i)
{
case add:
return a + b;
case sub:
return a - b;
case mul:
return a * b;
case divi:
return a / b;
}
};
cout<<func(add)<<endl;
return 0;
}
#include<iostream>
using namespace std;
int main()
{
int j = 10;
auto by_val_lambda = [=]{ return j + 1; };
auto by_ref_lambda = [&]{ return j + 1; };
cout<<"by_val_lambda: "<<by_val_lambda()<<endl;
cout<<"by_ref_lambda: "<<by_ref_lambda()<<endl;
++j;
cout<<"by_val_lambda: "<<by_val_lambda()<<endl;
cout<<"by_ref_lambda: "<<by_ref_lambda()<<endl;
return 0;
}
lambda与仿函数
#include <iostream>
using namespace std;
class MyFunctor
{
public:
MyFunctor(int tmp) : round(tmp) {}
int operator()(int tmp) { return tmp + round; }
private:
int round;
};
int main()
{
//仿函数
int round = 2;
MyFunctor f1(round);//调用构造函数
cout << "result1 = " << f1(1) << endl; //operator()(int tmp)
//lambda表达式
auto f2 = [=](int tmp) -> int { return tmp + round; } ;
cout << "result2 = " << f2(1) << endl;
return 0;
}
lambda的优势
#include <vector>
#include <algorithm> //std::for_each
#include <iostream>
using namespace std;
vector<int> nums;
vector<int> largeNums;
class LNums
{
public:
LNums(int u) : ubound(u) {} //构造函数
void operator () (int i) const
{//仿函数
if (i > ubound)
{
largeNums.push_back(i);
}
}
private:
int ubound;
};
int main()
{
//初始化数据
for (auto i = 0; i < 10; ++i)
{
nums.push_back(i);
}
int ubound = 5;
//1、传统的for循环
for (auto itr = nums.begin(); itr != nums.end(); ++itr)
{
if (*itr > ubound)
{
largeNums.push_back(*itr);
}
}
//2、使用仿函数
for_each(nums.begin(), nums.end(), LNums(ubound));
//3、使用lambda函数和算法for_each
for_each(nums.begin(), nums.end(), [=](int i)
{
if (i > ubound)
{
largeNums.push_back(i);
}
}
);
//4、遍历元素
for_each(largeNums.begin(), largeNums.end(), [=](int i)
{
cout << i << ", ";
}
);
cout << endl;
return 0;
}