Lambda表达式是编程中很实用的工具,作为热门的,最受欢迎编程语言之一(大概?),C++11及其以后版本,也提供了对lambda表达式的支持,下面让我们逐步学习和了解C++中的Lambda表达式吧
首先我们先看一个lambda表达式的使用例子:
#include <algorithm>
void sort_by_abs(int *arr, int len){
// use C++ lambda as param of the sort function
std::sort(arr, arr+len, [](int a, int b){
return (std::abs(a) < std::abs(b));
});
}
观察得到,C++ lambda表达式基本结构如下:
[=]() mutable throw() -> type {
// lambda body
return ret_value;
}
接下来我们将逐个部份进行介绍。
Capture Clause
首先是第一部份[]。这一部份被称之为捕获语句(Capture Clause)。在这一部份,你可以捕获lambda声明时范围内的变量。你可以在周围环境中捕获需要的变量,同时可以选择捕获类型为值传递还是引用传递。
默认情况下,Capture语句中捕获的变量将会以值传递形式传递。
void func1()
{
int num, num2;
auto a = [num]() {}; // pass value
auto b = [&num]() {}; // pass reference
auto c = [&, num]() {}; // (default: reference) pass reference
auto d = [=, &num]() {}; // (default: value) pass reference
}
需要注意,配置默认捕获模式将会将周围环境的所有变量暴露给lambda表达式。如上述代码,lambda c和d均设置了默认Capture设置,这种情况下,周围环境的所有变量都将会被Capture,c和d可以各自依照自己设定好的默认捕获模式访问到num2,但是a和b不能访问到num2。
同时,lambda表达式初始化时,也允许进行赋值操作,请看下面的代码。
void func()
{
int a, b, c = 0;
auto lambda = [a, b, &refToC = c]() mutable
{
refToC++;
cout << refToC << endl; // expected: 1
};
lambda();
cout << c << endl; // expected: 1
}
// output:
// 1
// 1
如上述代码,我们可以在lambda表达式的 Capture Clause 部分声明新的变量。新的声明变量同样可以是值传递或者引用传递。需要注意的是,在 Capture Clause 声明变量时,我们无需显式指定变量类型,lambda表达式会自动推断其类型(如上述代码中,refToC自动被推断为 int & 类型)
还有一个需要注意的点,默认情况下,Capture Clause 中捕获和声明的所有变量将会以const形式进行传递。也就是说lambda body中,默认不可以对 Capture Clause 中的变量进行更改。如果您想在 lambda body 中对 Capture Clause 中的值或者引用进行更新或修改,请在参数列表,函数体前加上mutable关键字。
2 thoughts on “Lambda Expression in C++”