声明:本文内容生成自ChatGPT,为方便大家了解学习作为引用到其他文章中。
C++ 中的 lambda 表达式 是一种简洁的语法,用于定义 匿名函数,即无需为函数命名的函数。它允许你在函数体内定义和使用临时的可调用对象,非常适合用于回调、简化算法操作和避免定义冗长的小函数。
Lambda 表达式的语法
[capture](parameters) -> return_type {// function body
}
各部分的解释:
capture
:捕获列表,用于捕获作用域中的变量。parameters
:参数列表,类似于普通函数的参数。return_type
:返回类型(可选)。可以自动推导,也可以显式指定。function body
:函数体,表示 lambda 表达式的具体执行逻辑。
示例
1. 最简单的 lambda
#include <iostream>int main() {auto greet = []() { std::cout << "Hello, World!" << std::endl; };greet(); // 调用 lambdareturn 0;
}
2. 带参数的 lambda
#include <iostream>int main() {auto add = [](int a, int b) { return a + b; };std::cout << "Sum: " << add(3, 4) << std::endl; // 输出: Sum: 7return 0;
}
3. 带捕获列表的 lambda
捕获列表用于捕获外部作用域中的变量。你可以通过值或引用来捕获变量。
- 按值捕获:捕获的变量的副本。
- 按引用捕获:捕获变量的引用,允许修改。
#include <iostream>int main() {int x = 10;int y = 20;// 按值捕获 x,按引用捕获 yauto lambda = [x, &y]() {std::cout << "x: " << x << ", y: " << y << std::endl;// y 可以修改,x 是捕获的副本,不能修改y += 10;};lambda(); // 输出: x: 10, y: 20std::cout << "y after lambda: " << y << std::endl; // 输出: y after lambda: 30return 0;
}
4. 捕获所有变量
- 使用
[=]
捕获外部作用域中的所有变量 按值 传递。 - 使用
[&]
捕获外部作用域中的所有变量 按引用 传递。
#include <iostream>int main() {int a = 5, b = 10;// 按值捕获所有变量auto lambda_by_value = [=]() {std::cout << "a: " << a << ", b: " << b << std::endl;};// 按引用捕获所有变量auto lambda_by_ref = [&]() {a += 10;b += 20;};lambda_by_value(); // 输出: a: 5, b: 10lambda_by_ref(); // 修改外部变量std::cout << "a: " << a << ", b: " << b << std::endl; // 输出: a: 15, b: 30return 0;
}
5. 指定返回类型
如果 lambda 表达式的返回类型不能自动推导,或者返回类型是复杂的类型,可以显式指定返回类型。
#include <iostream>int main() {auto divide = [](int a, int b) -> double {return static_cast<double>(a) / b;};std::cout << "Result: " << divide(10, 3) << std::endl; // 输出: Result: 3.33333return 0;
}
常见用途
1. 与标准库算法配合使用
Lambda 表达式常用于标准库的算法中,如 std::for_each
, std::sort
, std::transform
等。
#include <iostream>
#include <vector>
#include <algorithm>int main() {std::vector<int> vec = {5, 2, 9, 1, 5, 6};// 使用 lambda 表达式进行排序std::sort(vec.begin(), vec.end(), [](int a, int b) {return a < b;});// 使用 lambda 表达式遍历并输出std::for_each(vec.begin(), vec.end(), [](int n) {std::cout << n << " ";});std::cout << std::endl;return 0;
}
2. 捕获外部变量并用于回调函数
Lambda 表达式适合在事件驱动或回调场景中使用。
#include <iostream>
#include <functional>void performTask(std::function<void()> task) {task();
}int main() {int counter = 0;performTask([&counter]() {counter += 1;std::cout << "Counter: " << counter << std::endl;});return 0;
}
总结
- 捕获方式:通过捕获列表
[ ]
指定捕获外部变量的方式。 - 简洁性:可以用 lambda 表达式代替简单的函数或函数对象,简化代码。
- 应用场景:适合临时、匿名的可调用对象,特别是在回调、算法、事件处理中广泛应用。