Lambda表达式,又称匿名函数,假如在编程时,有一个函数只会被复用一次,其他地方再也不会调用时,lambda表达式就很实用。
1.Lambda表达式的基本语法
[ 捕获列表 ] ( 参数列表 ) -> 返回类型 { 函数体 }
语法:[capture list] (parameter list) -> return type {function body}
- capture list:表示捕获列表,是一个lambda所在函数中定义的局部变量列表;
- parameter list:表示参数列表;
- return type:返回类型;
- function body:函数体。
可以忽略参数列表和返回类型,但必须永远包含捕获列表和函数体,忽略参数列表等价于指定一个空函数列表,忽略返回类型,lambda会根据函数体中的代码推断出来。(如果函数体直接return,则是void类型)
举例:
正常的函数是这样:
int Foo(int a, int b)
{
return a+b;
}
则在主函数中,匿名函数就可以这样写
int main()
{
auto c = [ ] ( int a, int b ) -> int
{
return a+b;
}
}
#include <iostream>
#include <thread>
using namespace std;
int main(void)
{
string str = "test";
thread fun = thread([&str](int a, int b) {
cout << str << endl;
cout << a + b << endl;
}, 2, 3);
fun.join();
}
2.Lambda表达式的捕获方式
[ ]
:方括号里面为空表示不捕获外围的变量(即Lambda函数可以访问甚至是修改函数外部的变量)[N, &M]
:方括号中如果变量名M前面有引用符号,表示按引用捕获,可以修改外围变量的值;如果变量名N前面没有引用符号,表示按值捕获,不可以修改外围变量的值[&]
:方括号里面只写引用符号,那么就会按照引用捕获所有的封闭范围中的变量
Lambda表达式内部可以修改捕获的变量,因为它们以引用的方式捕获。
int main() {
int x = 5;
auto func = [&]() {
x = 10; // 可以修改外部变量x
};
func();
std::cout << x << std::endl; // 输出为10
return 0;
}
[=]
:方括号里面只写等号,意思是所有的变量都按值捕获
Lambda表达式内部不能修改捕获的变量,因为它们以值的方式捕获。
int main() {
int x = 5;
auto func = [=]() {
// x = 10; // 无法修改外部变量x,会导致编译错误
};
func();
std::cout << x << std::endl; // 输出为5
return 0;
}
[&, =N]
:可以单独指定一些变量按照值捕获,其他变量都按引用捕获,比如这里就是按值捕获N,其他变量按引用捕获[this]
:如果是在某个class中使用匿名函数,可以用this捕获当前实例的指针(C++17后,还可以用[*this],按值捕获该实例)