23. Labda表达式
一、什么是Lambda函数
Lambda 函数是 C++11标准新增的语法糖,也称为 Lambda 表达式或匿名函数。Lambda 表达式是一种在被调用的位置或作为参数传递给函数的位置定义匿名函数对象(闭包)的简便方法。Lambda 表达式的基本语法如下:
[capture list] (parameter list) -> return type { function body }
capture list
是 捕获列表,用于指定 Lambda 表达式可以访问的外部变量,以及是按值还是按引用的方式访问。捕获列表可以为空,表示不访问任何外部变量,也可以使用默认捕获模式 & 或 = 来表示按引用或按值捕获所有外部变量,还可以混合使用具体的变量名和默认捕获模式来指定不同的捕获方式。parameter list
是 参数列表,用于表示 Lambda 表达式的参数,可以为空,表示没有参数,也可以和普通函数一样指定参数的类型和名称,但不能有默认参数,还可以在 C++ 14 中使用 auto 关键字来实现泛型参数。return type
是 返回值类型,用于指定 Lambda 表达式的返回值类型,可以省略,表示由编译器根据函数体推导,也可以使用 -> 符号显式指定,还可以在 C++ 14 中使用 auto 关键字来实现泛型返回值。function body
是函数体,用于表示 Lambda 表达式的具体逻辑,可以是一条语句,也可以是多条语句,还可以在 C++ 14 中使用 constexpr 来实现编译期计算。
#include <iostream>
#include <list>
using namespace std;
struct Person
{
string name;
int age;
};
void printList(const list<Person> &l);
int main(void)
{
Person p1 = {"Sakura", 10};
Person p2 = {"Mikoto", 14};
Person p3 = {"Shana", 15};
Person p4 = {"Sakura", 12};
list<Person> l = {p1, p2, p3, p4};
printList(l);
cout << endl;
l.sort([](Person &p1, Person &p2) { return (p1.name == p2.name) ? (p1.age < p2.age) : (p1.name < p2.name); });
printList(l);
return 0;
}
void printList(const list<Person> &l)
{
for (list<Person>::const_iterator it = l.begin(); it != l.end(); it++)
{
cout << "{name: " << it->name << ", age: " << it->age << "}" << endl;
}
}
二、Lambda表达式的捕获列表
通过捕获列表,Lambda 函数可以访问的父作用域中的非静态局部变量(静态局部变量可以直接访问)。捕获列表在书写 [] 中,与函数参数的传递类似,捕获方式也可以是值或者引用。
捕获方式 | 含义 |
---|---|
[] | 空捕获列表,Lambda 不能使用所在函数中的变量 |
[identifier_list] | identifier_list 是一个逗号分隔的名字列表,这些名字都是 Lambda 所在函数的局部变量。默认情况下是值捕获 |
[=] | 采用值捕获方式 |
[&] | 采用引用捕获方式 |
[=, identifier_list] | 默认以值捕获变量,但 identifier_list 中变量采用引用捕获 |
[&, identifier_list] | 默认以引用方式捕获变量,但 identifier_list 中变量采用值捕获 |
#include <iostream>
using namespace std;
int main(void)
{
string str = "Hello Sakura!";
auto f = [str](void) ->void { cout << str << endl; };
// 像普通函数一样使用Lambda函数
f();
return 0;
}