在 c++++ 中,匿名函数(lambda 表达式)和函数对象(仿函数)可以通过捕获来访问外部变量:匿名函数通过 lambda 表达式语法捕获变量,支持按值 ([=])、按引用 ([&]) 或显式指定变量捕获。函数对象通过构造函数或运算符重载捕获变量,捕获模式与 lambda 表达式类似。捕获变量适用于算法、并发编程和事件处理等领域,但需要注意外部变量的生命周期、过度捕获的性能问题和修改外部变量的后果。
C++ 中捕获变量在匿名函数和函数对象中的作用
在 C++ 中,匿名函数(称为 lambda 表达式)和函数对象(称为仿函数)广泛用于编写可重用的代码块。一个关键特性是这些函数可以访问和修改其创建作用域中的外部变量,称为捕获变量。
匿名函数中的捕捉
立即学习“C++免费学习笔记(深入)”;
点击下载“修复打印机驱动工具”;
匿名函数使用 lambda 表达式语法创建,该语法允许捕获外部变量。有三种主要的捕获模式:
- [&]:捕获所有外部变量。(按引用捕获)
- [=]:捕获所有外部变量,但只按值捕获。(此模式也称为“值捕获”)
- [variable-list]:显式地捕获指定的外部变量。(可以按引用或按值捕获)
代码示例:
// 按值捕获外部变量
int x = 10;
auto lambda = [=]() {
std::cout << x << std::endl; // 值捕获,x 的值是 10
x++; // 无法修改外部 x 的值
};
// 按引用捕获外部变量
int y = 20;
auto lambda2 = [&]() {
std::cout << y << std::endl; // 按引用捕获,y 的值是 20
y++; // 可以修改外部 y 的值
};
函数对象中的捕捉
仿函数是派生自 std::function
代码示例:
class MyFunctor {
private:
int z; // 要捕获的外部变量
public:
MyFunctor(int z) : z(z) {} // 构造函数捕获 z
void operator()() { std::cout << z << std::endl; } // 运算符重载
};
int main() {
int a = 30;
MyFunctor functor(a);
functor(); // 打印 30
}
实战案例:
捕获变量在算法、并发编程和事件处理中非常有用。例如,可以创建一个 lambda 表达式,该表达式在排序算法中使用外部比较函数来比较元素。
注意:
处理捕获变量时应注意以下事项:
- 外部变量的生命周期必须涵盖匿名函数或函数对象的作用域。
- 过度捕获变量可能会导致性能问题和内存泄漏。
- 谨慎使用修改外部变量的捕获函数,因为它们可以产生意外的后果。