lambda
Lambda表达式是C++11及更新版本中引入的一种简洁、直观的创建匿名函数的方法。它允许在代码中快速定义并立即使用一个小型函数对象,而无需为其命名或写一个完整的函数定义。Lambda表达式的语法如下:
[capture-list] (parameters-list) mutable -> return-type { function-body }
各部分的含义:
-
[capture-list]
:捕获列表,用于决定lambda函数可以访问哪些外部变量。它可以是:[]
:不捕获任何外部变量。[=]
:捕获外部作用域的所有变量(按值捕获)。[&]
:捕获外部作用域的所有变量(按引用捕获)。[=,&this]
或[&,this]
:除了按值或按引用捕获之外,还捕获当前的this
指针。- 具体变量名:如
[x, &y]
,按值捕获x
,按引用捕获y
。
-
(parameters-list)
:参数列表,类似于普通函数的参数列表。 -
mutable
:可选关键字,表示即使lambda捕获的是外部变量的引用或副本,也可以在其主体内修改这些捕获的变量。 -
-> return-type
:可选的返回类型声明,如果编译器可以从函数体推断出返回类型,则可以省略。 -
{ function-body }
:函数体,包含lambda表达式要执行的代码。
示例:
#include <algorithm>
#include <vector>
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5};
std::sort(numbers.begin(), numbers.end(), [](int a, int b) { return a > b; }); // 按降序排序
// 示例2:使用捕获列表
int x = 10;
auto add_to_x = [x](int y) -> int { return x + y; }; // 捕获外部变量x,创建一个返回x与参数y之和的lambda函数
std::cout << add_to_x(5) << std::endl; // 输出15
return 0;
}
在上述示例中,第一个lambda表达式用于作为比较函数传递给std::sort
,第二个lambda表达式捕获了外部变量x
并创建了一个带有参数y
的函数,返回x
与y
的和。
匿名函数
匿名函数,又称为无名函数、lambda函数、闭包等,在不同的编程语言中有不同的表示和实现方式,但其核心概念是创建一个无需命名即可立即使用的函数对象。匿名函数通常用于简化临时函数的创建和使用,特别是在需要作为参数传递给其他函数或者在循环、条件语句等有限作用域内使用的场景。
在C++中,匿名函数可以通过lambda表达式来实现:
[]{
cout << "hello";
};
[](int x, int y) {
return x + y;
}
上述代码就是一个C++中的匿名函数(lambda表达式),它接受两个整数参数 x
和 y
,并返回它们的和。虽然它没有名称,但仍可以赋值给一个变量,然后像普通函数一样调用:
auto add = [](int x, int y) {
return x + y;
};
auto f = []{
cout << "hello";
};
int result = add(3, 4); // result现在是7
f(); // hello
lambda表达式实现递归
在C++中,lambda表达式自身并不能直接实现递归,因为lambda表达式不允许自己调用自己。然而,可以通过将lambda表达式赋值给一个具名函数对象或者函数指针,然后通过这个指针来实现递归。
#include <iostream>
int main() {
auto factorial = [](int n, auto self) -> int {
if(n < 0)return 0;
return self(n - 1, self);
};
function<int(int)> fact = [&](int n) -> int {
if(n < 0)return 0;
return fact(n - 1);
};
// 通过std::function包装lambda表达式可以存储更复杂的类型
std::function<int(int, decltype(factorial))> f = factorial;
return 0;
}
第一个lambda表达式factorial
通过第二个参数self
实现递归调用。在调用时,我们将lambda本身作为第二个参数传递,从而形成了递归调用链。
第二个则将自身以引用的方式到fact
函数中,从而实现了递归。