利用Lambda表达式,可以方便的定义和创建匿名函数。Lambda 表达式把函数看作对象。Lambda 表达式可以像对象一样使用,比如可以将它们赋给变量和作为参数传递,还可以像函数一样对其求值。
当一个函数需要将另一个函数用作参数时,可以使用 Lambda。
lambda表达式声明
[capture list] (params list) mutable exception-> return type { function body }
含义说明
capture list:捕获外部变量列表
params list:形参列表
mutable指示符:用来说用是否可以修改捕获的变量
exception:异常设定
return type:返回类型
function body:函数体
基本语法
[](int x, int y){ return x < y ; }
例如
#include <iostream>
int main()
{
int a = 1, b = 1, c = 1;
auto m1 = [a, &b, &c]() mutable {
auto m2 = [a, b, &c]() mutable {
std::cout << a << b << c << '\n';
a = 4; b = 4; c = 4;
};
a = 3; b = 3; c = 3;
m2();
};
a = 2; b = 2; c = 2;
m1(); // 调用 m2() 并打印 123
std::cout << a << b << c << '\n'; // 打印 234
}
例2 外部变量
Lambda表达式可以使用其可见范围内的外部变量,但必须明确声明(明确声明哪些外部变量可以被该Lambda表达式使用)。
#include <iostream>
using namespace std;
int main()
{
int a = 123;
auto f = [a] { cout << a << endl; };
f(); // 输出:123
//或通过“函数体”后面的‘()’传入参数
auto x = [](int a){cout << a << endl;}(123);
}
例3 值捕获
值捕获和参数传递中的值传递类似,被捕获的变量的值在Lambda表达式创建时通过值拷贝的方式传入,因此随后对该变量的修改不会影响影响Lambda表达式中的值。
int main()
{
int a = 123;
auto f = [a] { cout << a << endl; };
a = 321;
f(); // 输出:123
}
例4 引用捕获
使用引用捕获一个外部变量,只需要在捕获列表变量前面加上一个引用说明符&
int main()
{
int a = 123;
auto f = [&a] { cout << a << endl; };
a = 321;
f(); // 输出:321
}
例5 隐式捕获
让编译器根据函数体中的代码来推断需要捕获哪些变量,这种方式称之为隐式捕获。隐式捕获有两种方式,分别是[=]
和[&]
。[=]
表示以值捕获的方式捕获外部变量,[&]
表示以引用捕获的方式捕获外部变量。
隐式值捕获
int main()
{
int a = 123;
auto f = [=] { cout << a << endl; }; // 值捕获
f(); // 输出:123
}
隐式引用捕获
int main()
{
int a = 123;
auto f = [&] { cout << a << endl; }; // 引用捕获
a = 321;
f(); // 输出:321
}
Lambda表达式参数说明
Lambda表达式的参数和普通函数的参数类似,但是Lambda表达式中传递参数还有一些限制,主要有以下几点:
- 参数列表中不能有默认参数
- 所有参数必须有参数名
- 不支持可变参数
例如
int main{
int m = [](int x) { return [](int y) { return y * 2; }(x)+6; }(5);
std::cout << "m:" << m << std::endl; //输出m:16
std::cout << "n:" << [](int x, int y) { return x + y; }(5, 4) << std::endl; //输出n:9
auto gFunc = [](int x) -> function<int(int)> { return [=](int y) { return x + y; }; };
auto lFunc = gFunc(4);
std::cout << lFunc(5) << std::endl;
auto hFunc = [](const function<int(int)>& f, int z) { return f(z) + 1; };
auto a = hFunc(gFunc(7), 8);
int a = 111, b = 222;
auto func = [=, &b]()mutable { a = 22; b = 333; std::cout << "a:" << a << " b:" << b << std::endl; };
func();
std::cout << "a:" << a << " b:" << b << std::endl;
a = 333;
auto func2 = [=, &a] { a = 444; std::cout << "a:" << a << " b:" << b << std::endl; };
func2();
auto func3 = [](int x) ->function<int(int)> { return [=](int y) { return x + y; }; };
std::function<void(int x)> f_display_42 = [](int x) { print_num(x); };
f_display_42(44);
}