lambda被用来表示一种匿名函数,这种匿名函数代表了一种所谓的lambda calculus。以lambda概念为基础的”函数式编程“是与命令式编程、面向对象编程等并列的一种编程范型。
[capture](parameters)mutable ->return-type{statement}
其中,
- [capture] :捕捉列表,[]是lambda引出符,编译器根据该引出符判断接下来的代码是否是lambda函数。捕捉列表用于捕捉父域中的变量以供lambda函数使用,捕捉列表可以由多个项组成,用","分割。[var]表示以值传递方式捕捉父域中的变量var,[=]表示以值传递方式捕捉父域中的所有变量(包括this),[&var]表示以引用传递方式捕捉父域中的变量var,[&]表示以引用传递方式捕捉父域中的所有变量(包括this),[this]表示以值传递方式捕捉当前的this指针。
- (parameters):参数列表,与普通函数的参数列表一致,如果不需要参数传递,则可以连同括号()一起省略。
- mutable: mutable修饰符,默认情况下,lambda函数总是一个const函数,mutable可以取消其常量性。在使用该修饰符时,参数列表不可省略(即使参数为空)。
- ->return-type: 返回类型,用追踪返回类型形式声明函数的返回类型,不需要返回值的时候可以连同符号->一起省略。在返回类型明确的情况下,也可以省略该部分,让编译器对返回类型进行推导。
- {statement}: 函数体,内容与普通函数一样,不过除了可以使用参数之外,还可以使用所有捕获的变量。
注意:
1.lambda无法修改按值捕获的外部变量,如果需要修改外部变量,可以通过引用方式捕获。
2.lambda表达式的延迟调用, 真正开始调用的时候,才执行lambda表达式。
int a = 0;
auto f = [=]{return a;};
a += 1;
cout << f() << endl;
输出a=0;
作用:
1.代替静态函数,相当于是仿函数的作用
#include <iostream>
int main()
{
int a = 3;
int b = 4;
int c = 5;
auto fun = [=, &b](int c) ->int {
return b += a + c;
};
std::cout << "fun ret=" << fun(c) << std::endl;// 打印12
std::cout << "b =" << b << std::endl;// 打印12
}
例如调用<algorithm>中的std::sort,ISO C++ 98 的写法是要先写一个compare函数:
1 2 3 4 |
|
然后,再这样调用:
1 |
|
然而,用ISO C++ 11 标准新增的Lambda表达式,可以这么写:
1 |
|
std::vector<string> vecs;
vecs.push_back("1");
vecs.push_back("asd");
std::vector<string> vecm = std::move(vecs); // 免去很多拷贝
std::sort(vecm.begin(), vecm.end(), [](string a, string b) ->bool{return a > b; });
这样一来,代码明显简洁多了。
2.对于没有捕获任何变量的lambda表达式,还可以被转换成一个普通的函数指针。
using func_t = int(*)(int);
func_t f = [](int a){return a;};
f(123);
3.通过std::function和std::bind来存储和操作lambda表达式
std::function<int(int)> f1 = [](int a){return a;};
std::function<int(void)> f2 = std::bind([](int a){return a;},123);