温馨提示
本文最后更新于 天前,其中的信息可能已经有所发展或是发生改变。
目录
lambda的表达方法及其区别
1.lambde的方法一 []()
1.注意事项
- 这个方法的作用域只限于它自己,不能使用外部变量
- 如果尝试在
[]的 Lambda 中使用外部变量,会产生编译错误
2.特点
Lambda 不能访问任何外部的变量,只能操作传递给它的参数或者使用 Lambda 内部声明的变量。
3.用法
当你不需要在 Lambda 中使用外部作用域的变量时,可以用空捕获列表 []
1.当你不需要捕获变量时
void someFunction() {
int x = 10;
auto lambda = []() {
// 不捕获任何变量,无法访问 x
std::cout << "This will not access x" << std::endl;
};
lambda();
}2.当你想要捕获一个以及多个变量时
// 这是捕获一个值的方法
void someFunction() {
int x = 10;
auto lambda = [x]() { // 通过值捕获 x
std::cout << x << std::endl;
};
lambda();
}2.方法2 [&]()
1.主要事项
- 需要确保 Lambda 的生命周期不会超出捕获的外部变量的生命周期,否则就会导致未定义行为(Dangling Reference)。
[&]捕获的是所有外部变量引用,如果只想捕获特定变量,最好手动列出。
2.特点
- 捕获所有外部变量的引用,允许 Lambda 内对它们进行修改。
- 修改外部变量会直接影响原始变量。
3.用法
用 [&] 捕获外部作用域的所有变量通过引用,这意味着你可以在 Lambda 中修改外部变量,它们的值会在 Lambda 外部同步更新。
void someFunction() {
int x = 10;
auto lambda = [&]() {
// 通过引用捕获 x,可以修改外部的 x
x = 20;
std::cout << x << std::endl; // 输出 20
};
lambda();
std::cout << x << std::endl; // 外部的 x 也变成了 20
}3.方法三 [*]()
1.注意事项
- 如果 Lambda 内需要修改外部变量并同步到外部,
[*]是不适合的,你需要改用[&]或手动捕获引用。 - 在捕获大对象时,捕获整个作用域的值可能会有性能开销。
2.特点
- 捕获所有外部变量的值,即 Lambda 内的变量是独立的拷贝,修改不会影响外部变量。
- Lambda 使用的是外部变量的快照,执行时外部变量的变化不会反映到 Lambda 内部。
3.用法
void someFunction() {
int x = 10;
auto lambda = [*]() {
// 捕获外部变量 x 的值,但无法修改外部的 x
std::cout << x << std::endl; // 输出 10
};
lambda();
x = 30;
lambda(); // 再次调用,仍然输出 10,因为它捕获的是初始的 x 值
}2.其他注意事项
- 生命周期问题:在使用
[&]捕获外部变量时,一定要确保 Lambda 的生命周期不会超过外部变量的生命周期,否则会导致引用悬挂的错误。 - 捕获特定变量:可以只捕获部分外部变量,而不是全部。例如
[x, &y]表示通过值捕获x,通过引用捕获y。 - 捕获
this指针:如果你在类的成员函数中使用 Lambda,可以用[this]捕获当前对象的指针,方便访问成员变量和成员函数。
class MyClass {
public:
int value = 100;
void myMethod() {
auto lambda = [this]() {
std::cout << value << std::endl; // 通过 this 捕获成员变量
};
lambda();
}
};3.总结
**[]**:不捕获外部变量,完全独立。**[&]**:捕获所有外部变量的引用,可以修改外部变量。**[*]**:捕获所有外部变量的值,修改 Lambda 内部变量不会影响外部变量。
希望我的博客能够对你有帮助

评论
评论区还没开放,部署评论服务后就能留言啦~