内容来自《C++ Primer》第五版:
一个lambda表达式表示一个可调用的代码单元,可以将其理解成一个未命名的内联函数。与任何函数类似,一个lambda具有一个返回类型、一个参数列表和一个函数体。具体形式是:
1 // capture list(捕获列表)是一个lambda所在函数中定义的局部变量的列表,通常为空; 2 // return type, parameter list 和 function body与任何普通函数一样 3 // lambda必须使用尾置返回来指定返回类型. 4 [capture list](parameter list) -> return type { funcion body} 5 6 // 定义一个可调用对象f 7 auto f = [] { return 42; } 8 9 // lambda的调用方式与普通函数的调用方式相同 10 cout << f() << endl;
1. 向lambda传递参数
调用一个lambda时给定的实参被用来初始化lambda的形参,lambda不能有默认参数。
1 stable_sort(words.begin(), words.end(), 2 [](const string &a, const string &b) { 3 return a.size() < b.size(); 4 });
2. 使用捕获列表
一个lambda通过将局部变量包含在其捕获列表中来指出将会指明将会使用这些变量。捕获列表指引lambda在其内包含访问局部变量所需的信息。
1 // lambda捕获sz 2 [sz](const string &a) { return a.size() >= sz; };
捕获列表只用于局部非static变量,lambda可以直接使用局部static变量和在它所在函数之外声明的名字。
3. lambda捕获和返回
值捕获: 采用值捕获的前提是变量可以拷贝,修改不会影响到lambda内对应得值;
1 void fun1() { 2 size_t v1 = 42; 3 auto f = [v1] { return v1; }; 4 v1 = 0; 5 auto j = f(); 6 }
引用捕获:
void fun2() { size_t v1 = 42; auto f = [&v1] { return v1; }; v1 = 0; auto j = f(); // j = 0 }
隐式捕获:&告诉编译器采用捕获引用方式, =则表示采用值捕获方式:
1 wc = find_if(words.begin(), words.end(), [=](const string &s) { return s.size() >= sz;});
可以混合使用隐式捕获和显式捕获:
for_each(words.begin(), words.end(), [&, c](const string &s) { os << s << c;});
可变lambda:
我们可以通过添加关键字mutable来改变一个被捕获的变量值:
1 void fcn3() { 2 size_t v1 = 42; 3 auto f = [v1]() mutable { return ++v1;}; 4 v1 = 0; 5 auto j = f(); 6 }
4. 参数绑定
使用标准库bind函数,bind函数定义在头文件functional中,可以将bind函数看作一个通用的函数适配器,它接受一个可调用对象,生成一个新的可调用的对象来适应原函数的参数列表。bind调用的一半形式为:
1 auto newCallable = bind(callable, arg_list);