在 C++ 的 lambda 表达式中,捕获列表的内容决定了如何访问外部变量。以下是关于捕获列表的详细解释和 lambda 表达式的常见用法:
捕获列表中的使用
-
[this]
:- 捕获当前对象的指针,使您能够访问成员变量和成员函数。
-
[&]
:- 捕获所有外部变量的引用(即以引用的方式捕获)。这意味着在 lambda 中对这些变量的修改会反映到其原始作用域中。
- 注意,捕获所有变量的引用是非常强大的,但也要小心使用,以避免悬空引用的问题。
-
[=]
:- 捕获所有外部变量的副本(即以值的方式捕获)。在 lambda 中对这些变量的修改不会影响原始变量,因为它们是副本。
-
选择性捕获:
- 你可以选择性地捕获具体的变量,例如:
[&var1, var2]
:捕获var1
的引用,捕获var2
的副本。[=, &var1]
:捕获所有变量的副本,但以引用的方式捕获var1
。
- 你可以选择性地捕获具体的变量,例如:
lambda 表达式的常见用法:
-
传递回调函数:
- 可以将 lambda 表达式作为参数传递给其他函数,特别是在需要使用回调的场景中。
std::sort(vec.begin(), vec.end(), [](int a, int b) {return a < b; });
-
事件处理:
- 在 GUI 编程或其他需要事件处理的场合,使用 lambda 表达式可以简化回调定义。
button.onClick([]() {std::cout << "Button clicked!" << std::endl; });
-
异步编程:
- 在多线程编程中,lambda 可用于实现异步操作。
std::thread([=]() {// 在新线程中执行的代码 }).detach();
-
简化代码逻辑:
- 使用 lambda 可以避免定义单独的函数,在简单操作或一次性事件中更加清晰。
auto result = std::transform(vec.begin(), vec.end(), output.begin(),[](int x) { return x * 2; });
总结:
- 捕获列表允许您决定在哪个作用域内使用变量,并控制变量的生存期和修改能力。
- 使用
[&]
捕获所有外部变量的引用,适合需要在 lambda 内部修改外部变量的场景,但要谨慎使用以避免悬空引用。 - 常见的用法包括回调函数、事件处理、异步编程和逻辑简化,使代码更加简洁和高效。