1、Lambda 表达式和匿名函数的区别:匿名函数是一个广泛的概念,用于描述没有名字的函数,Lambda 表达式是一种特定的匿名函数实现。在许多编程语言中,Lambda 表达式可以捕获外部变量的上下文(即闭包),而传统的匿名函数则不总是具备这种能力。
2、Lambda 表达式的主要作用:Lambda表达式使得可以在需要函数作为参数的情况下,快速定义函数,而不需要事先声明一个函数。
3、Lambda 表达式的基本语法:
[capture](parameters) -> return_type {
// function body
}
capture:指定外部变量的捕获方式(如按值或按引用)。
parameters:参数列表,与普通函数类似。
return_type:返回类型(可以省略,编译器会推导)。
function body:函数体。
4、示例1:在需要函数作为参数的情况下,快速定义函数,而不需要事先声明一个函数:
bool test(int(*fp)())// test函数需要一个函数作为参数,fp为函数指针
{
return fp() > 10;
}
int main()
{
bool flag = test([](){// 给test函数一个 lambda 表达式
return 5;
});
cout << "flag == " << flag << endl;// flag == 0
return 0;
}
示例2:Lambda 表达式可以在普通函数中定义和使用,但是普通函数不能在函数中定义:
int main()
{
auto greet = [](const string& name)
{
cout << "hello " + name << endl;
};
greet("tom");// hello tom
return 0;
}
示例3:Lambda 表达式可以捕获外部变量。[ ]就是捕获列表,所谓捕获列表,其实可以理解为参数的一种类型,Lambda 表达式内部函数体在默认情况下是不能够使用函数体外部的变量的, 这时候捕获列表可以起到传递外部数据的作用:
int main()
{
// 定义两个外部变量
int x = 10;
int y = 20;
// 方式一:按值捕获外部变量
auto add = [x, y]()
{
//x = 100; 报错,此时无法修改按值捕获的外部变量
return x + y;
};
cout << add() << endl;// 30
// 方式二:按引用捕获外部变量
auto sub = [&x, &y]()
{
x = 100;// 可以修改按引用捕获的外部变量
return x - y;
};
cout << sub() << endl;// 80
cout << "x == " << x << endl;// x == 100,外部变量 x 也被修改
return 0;
}
5、隐式捕获(自动捕获周围作用域中的变量),手动书写捕获列表有时候是非常复杂的,这种机械性的工作可以交给编译器来处理,这时候可以在捕获列表中写一个 & 或 = ,向编译器声明采用引用捕获或者值捕获,让编译器自行推导引用列表:
int main()
{
// 定义两个外部变量
int x = 10;
int y = 20;
// 方式一:按值捕获两个外部变量
auto add = [=]()
{
//x = 100; 报错,此时无法修改按值捕获的外部变量
return x + y;
};
cout << add() << endl;// 30
// 方式二:按引用捕获两个外部变量
auto sub = [&]()
{
x = 100;// 可以修改按引用捕获的外部变量
return x - y;
};
cout << sub() << endl;// 80
return 0;
}
6、值得注意的是,如果不使用按引用捕获外部变量的方式,但也想修改外部变量,可以使用 mutable 关键字,但是外部变量本身没有被修改
int main()
{
// 定义两个外部变量
int x = 10;
int y = 20;
// 方式一:按值捕获外部变量
auto add = [x, y]() mutable {
x = 100;// 可以修改按值捕获的外部变量
return x + y;
};
cout << add() << endl;// 120
cout << "x == " << x << endl;// x == 10,外部变量 x 本身没有被修改
return 0;
}