Lambda 表达式
Lambda 表达式是 C++11
引入的一种
匿名函数
的方式,它允许你在需要函数的地方内联地定义函数,而无需单独命名函数
Lambda
表达式的基本语法如下:
[ capture clause ]( parameters ) -> return_type {// 函数体// 可以使用捕获列表中的变量return expression ; // 可选的返回语句}
Lambda 表达式由以下部分组成:
捕获列表(
Capture clause
)
:用于捕获外部变量,在
Lambda
表达式中可以访问这些变量。捕
获列表可以为空,也可以包含变量列表
[var1, var2, ...]
。
参数列表(
Parameters
)
:与普通函数的参数列表类似,可以为空或包含参数列表
(param1, param2, ...) 。
返回类型(
Return type
)
:
Lambda
表达式可以自动推断返回类型
auto
,也可以显式指定返回类
型
-> return_type
。如果函数体只有一条返回语句,可以省略返回类型。
函数体(
Body
)
:
Lambda
表达式的函数体,包含需要执行的代码。
Lambda
表达式最简单的案例是在需要一个小型函数或临时函数时直接使用它。以下是一个非常简单的
例子,其中使用
Lambda
表达式来定义一个加法操作,并立即使用它来计算两个数的和。
示例:使用 Lambda 表达式进行加法
#include <iostream>
int main() {
// 定义一个简单的 Lambda 表达式进行加法
auto add = [](int a, int b) {
return a + b;
};
// 使用 Lambda 表达式计算两个数的和
int sum = add(10, 20);
std::cout << "Sum is: " << sum << std::endl;
return 0;
}
在这个例子中:
我们定义了一个名为
add
的
Lambda
表达式,它接受两个整数参数,并返回它们的和。
然后,我们使用这个
Lambda
表达式来计算两个数字(
10
和
20
)的和,并将结果存储在变量
sum
中。
最后,我们打印出这个和。
这个例子展示了
Lambda
表达式的基本用法:作为一种简洁而快速的方式来定义小型函数。
我们可以写一个例子,其中使用一个函数来找出两个数中的较大数,这个函数将接受一个
lambda
函数
作为回调来比较这两个数。
Lambda
函数将直接在函数调用时定义,完全是匿名的。
先回忆以下回调函数
bool myCompare(int a, int b){
return a > b;
}
int getMax(int a, int b, bool(*compare)(int, int)) {
if (compare(a, b)) {
return a;
} else {
return b;
}
}
int main() {
int x = 10;
int y = 20;
// 回调函数
int max = getMax(x, y, myCompare);
std::cout << "The larger number is: " << max << std::endl;
return 0;
}
示例:使用匿名 Lambda 函数来返回两个数中的较大数
#include <iostream>
// 函数,接受两个整数和一个比较的 lambda 函数
bool myCompare(int a, int b){
return a > b;
}
int getMax(int a, int b, bool(*compare)(int, int)) {
if (compare(a, b)) {
return a;
} else {
return b;
}
}
int main() {
int x = 10;
int y = 20;
// 回调函数
int max = getMax(x, y, [](int a,int b){
return a>b;
});
std::cout << "The larger number is: " << max << std::endl;
return 0;
}
在这个例子中:
getMax
函数接受两个整数
a
和
b
,以及一个比较函数
compare
。这个比较函数是一个指向函数
的指针,它接受两个整数并返回一个布尔值。
在
main
函数中,我们调用
getMax
,并直接在调用点定义了一个匿名的
lambda
函数。这个
lambda
函数接受两个整数并返回一个表示第一个整数是否大于第二个整数的布尔值。
这个
lambda
函数在
getMax
中被用作比较两个数的逻辑。根据
lambda
函数的返回值,
getMax
返回较大的数。
这个例子展示了如何直接在函数调用中使用匿名
lambda
函数,使代码更加简洁和直接。这种方法在需
要临时函数逻辑的场合非常有用,尤其是在比较、条件检查或小型回调中。
在
Lambda
表达式中,参数捕获是指
Lambda
表达式从其定义的上下文中捕获变量的能力。这使得
Lambda
可以使用并操作在其外部定义的变量。捕获可以按值(拷贝)或按引用进行。
让我们通过一个简单的示例来展示带参数捕获的
Lambda
表达式。
示例:使用带参数捕获的 Lambda 表达式
#include <iostream>
using namespace std;
int main() {
int x = 10;
int y = 20;
// 捕获 x 和 y 以便在 Lambda 内部使用
// 这里的捕获列表 [x, y] 表示 x 和 y 被按值捕获
auto sum = [x, y]() {
// x++;
// y++; 按值捕获,关注的是值本身,无法修改
return x + y;
};
std::cout << "Sum is: " << sum() << std::endl;
std::cout << "x is now: " << x << ", y is now: " << y << std::endl;
// 捕获所有外部变量按值捕获(拷贝)
int z = 30;
auto multiply = [=]() {
// x++;
// y++; 按值捕获,关注的是值本身,无法修改
return x * y * z;
};
cout << x << "," << y << endl;
std::cout << "Product is: " << multiply() << std::endl;
std::cout << "x is now: " << x << ", y is now: " << y << std::endl;
// 捕获所有外部变量按引用捕获
auto modifyAndSum = [&]() {
x = 15; // 修改 x 的实际值
y = 25; // 修改 y 的实际值, 引用捕获可以修改
return x + y;
};
std::cout << "Modified Sum is: " << modifyAndSum() << std::endl;
std::cout << "x is now: " << x << ", y is now: " << y << std::endl;
return 0;
}
}
在这个例子中:
第一个
Lambda
表达式
sum
按值捕获了
x
和
y
(即它们的副本)。这意味着
sum
内的
x
和
y
是在
Lambda
定义时的值的拷贝。
第二个
Lambda
表达式
multiply
使用
[=]
捕获列表,这表示它按值捕获所有外部变量。
第三个
Lambda
表达式
modifyAndSum
使用
[&]
捕获列表,这表示它按引用捕获所有外部变量。
因此,它可以修改
x
和
y
的原始值。
这个示例展示了如何使用不同类型的捕获列表(按值和按引用)来控制
Lambda
表达式对外部变量的访 问和修改。按值捕获是安全的,但不允许修改原始变量,而按引用捕获允许修改原始量,但需要注意 引用的有效性和生命周期问题
以下是一个表格,概述了 Lambda 函数和内联函数在 C++ 中的相似之处和区别:
请注意,虽然
Lambda
函数和内联函数在某些方面有相似之处,如它们都可以被编译器优化以减少调用
开销,但它们在设计和用途上有明显的不同。
Lambda
函数的核心优势在于它们的匿名性和对外部变量
的捕获能力,而内联函数则主要关注于提高小型函数的性能。