Lambda 表达式(lambda expression)是一个匿名函数,从软件开发角度看,也是一种编程范型。C++11 开始支持函数式编程范型lambda。
lambda函数的语法定义如下:
[capture] (parameters) mutable ->return-type {statement}
其中,
[capture]: 捕捉列表。
捕捉列表总是出现在lambda函数的开始处。事实上,[]是lambda引出符。编译器根据该引出符判断接下来的代码是否是lambda函数。允许访问当前作用域下的某一个(些)变量
语法上,捕捉列表由多个捕捉项组成,并以逗号分割。捕捉列表有如下几种形式:
[var] 表示值传递方式捕捉变量var。
[=] 表示值传递方式捕捉所有父作用域的变量(包括this)。
[&var] 表示引用传递捕捉变量 var。
[&] 表示引用传递捕捉所有父作用域的变量(包括this)。
[this] 表示值传递方式捕捉当前的 this 指针。
[=,&var] 捕获当前作用域所有变量,以值传递,但以引用传递var(也可以使用[&,var]来进行值传递)
(parameters): 参数列表。
与普通函数的参数列表一致。如果不需要参数传递,则可以连同括号0一起省略。
mutable: mutable修饰符。
默认情况下,lambda丽数总是一个const函数,mutable可以取消其常量性。在使用该修饰符时,参数列表不可省略(即使参数为空)。
->return-type:返回类型。
用追踪返回类型形式声明函数的返回类型。出于方便,不需要返回值的时候也可以连同符号->一起省略。此外,在返回类型明确情况下,也可以省略,让编译器对返回类型进行推导。
{statement}: 函数体。
内容与普通函数一样,不过除了可以使用参数之外,还可以使用所有捕获的变量。
简单用例:
int main()
{
[]{}; //最简 lambda 函数(空函数)
int a=3;
int b=4;
auto c = [=] {return a+b;}; //省略了参数列表与返回类型,返回类型由编译器推断为int
std::cout<< c() <<std::endl;
auto funl=[&](intc){ba+c;}; //省略了返回类型,无返回值
auto fun2=〔=,&b](int c)->int(returnb+=a+c;}; //各部分都很完整的 lambda 函数
}
//编译选项:g++ -o xxx.CPP -std=c++11
lambad 与仿函数:
仿函数简单地说,就是重定义了成员函数operator ()的一种自定义类型对象。这样的对象有个特点,就是其使用在代码层面感觉跟函数的使用并无二样,但究其本质却并非函数。
class _functor{
public:
int operator() (int x,int y) {return x+y;} //重载operator()
};
int main(){
int a =3,b =4;
_functor total;
std::cout<< total(a,b) << std::endl;
std::cout<< [=] { return a+b;}() <<std::endl;
}
仿函数是编译器实现lambda的一种方式。在现阶段,通常编译器都会把lambda函数转化为成为一个仿函数对象。因此,在C++11中,lambda可以视为仿函数的一种等价形式.
注意: 有的时候,我们在编译时发现lambda函数出现了错误,编译器会提示一些构造函数等相关信息。这显然是由于lambda的这种实现方式造成的。理解了这种实现,用户也就能够正确理解错误信息的由来。