lambda表达式简介
当我们需要在某个地方定义一个简短的函数对象,但又不想专门为其定义一个函数或者函数对象时,lambda表达式就非常有用了。它是一种可以在代码中直接定义并使用的匿名函数。
lambda表达式的基本语法如下:
[capture list](parameter list) mutable(optional) exception attribute(optional) -> return type(optional) {
// function body
}
下面是各个部分的解释:
-
捕获列表(capture list):用于指定lambda函数体中需要访问的外部变量。捕获列表的形式可以是
[]
、[&]
、[=]
、[var]
、[&var]
、[=, &var]
等。[]
表示不捕获任何外部变量,[&]
表示引用所有外部变量,[=]
表示拷贝所有外部变量,[var]
表示只捕获变量var,[&var]
表示引用变量var,[=, &var]
表示拷贝所有外部变量,但引用变量var。捕获变量使得lambda函数可以在其函数体中访问和修改这些变量。 -
参数列表(parameter list):用于指定lambda函数的参数。可以为空,也可以包含一个或多个参数。参数列表的形式和普通函数的参数列表一样。
-
mutable(可选):用于指定lambda函数体是否可以修改捕获的外部变量。如果需要在lambda函数体中修改捕获的外部变量,就需要使用
mutable
关键字。 -
异常属性(exception attribute,可选):用于指定lambda函数可能抛出的异常。
-
返回类型(return type,可选):用于指定lambda函数的返回类型。如果没有指定返回类型,编译器会根据函数体自动推断返回类型。
-
函数体(function body):lambda函数的具体实现代码。
下面是一个简单的例子,展示了如何使用lambda表达式来实现一个简单的加法函数:
auto add = [](int a, int b) -> int {
return a + b;
};
int result = add(3, 4); // result = 7
在这个例子中,我们使用lambda表达式定义了一个加法函数,并将其赋值给变量add
。lambda函数的参数列表是(int a, int b)
,返回类型是int
。函数体是return a + b
,表示将两个参数相加并返回结果。然后,我们可以像调用普通函数一样使用add
变量来调用lambda函数。
lambda表达式的灵活性和简洁性使得其在很多场景下都非常有用,例如在算法中用作比较函数、在STL容器中用作谓词、在多线程编程中用作线程函数等等。
例子1 在算法中用作比较函数
当在算法中需要自定义比较函数时,lambda表达式可以提供一种简洁的方式。下面是一个例子,使用lambda表达式对一个整数数组进行排序:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> nums = {5, 2, 8, 3, 1};
// 使用lambda表达式作为比较函数
std::sort(nums.begin(), nums.end(), [](int a, int b) {
return a < b;
});
for (int num : nums) { // 输出排序后的数组
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
在上面的例子中,lambda表达式[](int a, int b) { return a < b; }
作为std::sort
函数的第三个参数,用于指定排序的规则。这个lambda表达式接受两个整数参数a
和b
,并返回一个布尔值表示a
是否小于b
。通过这种方式,我们可以根据自定义的比较规则对数组进行排序。
输出结果为:1 2 3 5 8,表示数组已按照升序排列。
举例 2 lambda表达式在STL容器中经常被用作谓词
lambda表达式在STL容器中经常被用作谓词,用于在算法中进行条件判断或筛选。下面是一个例子,使用lambda表达式作为谓词对一个整数数组进行筛选:
int main() {
std::vector<int> nums = {1, 2, 3, 4, 5};
// 使用lambda表达式作为谓词,筛选出大于2的元素
std::vector<int> filtered_nums;
std::copy_if(nums.begin(), nums.end(), std::back_inserter(filtered_nums), [](int num) {
return num > 2;
});
for (int num : filtered_nums) { // 输出筛选后的数组
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
在上面的例子中,lambda表达式[](int num) { return num > 2; }
作为std::copy_if
函数的第四个参数,用于指定筛选的条件。这个lambda表达式接受一个整数参数num
,并返回一个布尔值表示num
是否大于2。通过这种方式,我们可以根据自定义的条件筛选出符合要求的元素。
输出结果为:3 4 5,表示筛选出的数组元素大于2。
举例3 Lambda表达式可以用作线程函
Lambda表达式可以用作线程函数,在多线程编程中非常有用。通过Lambda表达式,我们可以直接定义线程函数的逻辑,而不需要显式地创建一个函数对象。
下面是一个示例,展示了如何在多线程编程中使用Lambda表达式作为线程函数:
#include <iostream>
#include <thread>
int main() {
// 创建一个线程,并使用Lambda表达式作为线程函数
std::thread t([](){
std::cout << "Hello from thread!" << std::endl;
});
// 等待线程执行完成
t.join();
return 0;
}
在这个示例中,我们使用Lambda表达式[](){}
定义了一个匿名的线程函数,该函数输出了一条简单的消息。然后,我们使用std::thread
类创建一个新的线程,并将Lambda表达式作为线程函数传递给它。最后,我们调用join()
函数等待线程执行完成。
通过使用Lambda表达式作为线程函数,我们可以更加方便地定义线程的逻辑,并且不需要额外定义一个函数对象。这样可以提高代码的简洁性和可读性。