C++ 封闭函数局部变量不能在 lambda 体中引用,除非其位于捕获列表中
在 C++ 中,lambda 表达式可以捕获外部作用域的变量,但为了能够在 lambda 体中使用这些变量,它们必须显式地列在 捕获列表 中。否则,这些变量就不能直接在 lambda 表达式内部使用。
为什么捕获列表很重要?
C++ 中的 lambda 表达式有一个非常重要的特性,就是它们 可以访问外部作用域的变量。但是为了保证 作用域的明确性和避免潜在的错误,C++ 要求在 lambda 的捕获列表中显式声明要捕获哪些外部变量。捕获列表就是位于 lambda 表达式的开始部分,用于捕获外部作用域中的变量。
示例 1:没有捕获的情况(编译错误)
cpp
#include <iostream>
void example() {
int x = 5;
// lambda 表达式没有捕获 x,所以不能在 lambda 体中使用 x
auto lambda = []() {
// 这里会导致编译错误,因为 x 没有被捕获
std::cout << x << std::endl;
};
lambda();
}
int main() {
example();
return 0;
}
错误信息:
error: 'x' was not declared in this scope
示例 2:正确的捕获变量(编译通过)
要在 lambda 中引用外部变量,必须在捕获列表中声明这些变量,或者使用捕获所有变量的方式:
- 2.1 捕获单个变量
cpp
#include <iostream>
void example() {
int x = 5;
// lambda 捕获外部变量 x
auto lambda = [x]() {
std::cout << x << std::endl; // 这里可以正确访问 x
};
lambda();
}
int main() {
example();
return 0;
}
输出:
5
- 2.2 捕获多个变量
cpp
#include <iostream>
void example() {
int x = 5;
int y = 10;
// lambda 捕获多个外部变量
auto lambda = [x, y]() {
std::cout << "x: " << x << ", y: " << y << std::endl;
};
lambda();
}
int main() {
example();
return 0;
}
输出:
x: 5, y: 10
- 2.3 捕获所有外部变量([=])
如果你想捕获外部作用域中的所有变量,你可以使用 [=] 语法:
cpp
#include <iostream>
void example() {
int x = 5;
int y = 10;
// 使用 [=] 捕获所有外部变量
auto lambda = [=]() {
std::cout << "x: " << x << ", y: " << y << std::endl;
};
lambda();
}
int main() {
example();
return 0;
}
输出:
x: 5, y: 10
- 2.4 捕获所有外部变量并允许修改([&])
如果你希望 lambda 可以修改外部作用域中的变量,你可以使用 [&] 来捕获所有变量,并通过引用来传递它们:
cpp
#include <iostream>
void example() {
int x = 5;
// 使用 [&] 捕获所有外部变量并按引用传递
auto lambda = [&]() {
x = 10; // 修改 x 的值
std::cout << "x: " << x << std::endl;
};
lambda();
std::cout << "x after lambda: " << x << std::endl;
}
int main() {
example();
return 0;
}
输出:
x: 10
x after lambda: 10
总结
- lambda 表达式 不允许直接使用外部作用域中的变量,除非它们被显式地捕获。
- 捕获列表 [x] 可以捕获一个或多个外部变量,[=] 可以捕获所有外部变量(按值),而 [&] 捕获所有外部变量(按引用)。
- 如果没有捕获列表,lambda 内部不能直接访问外部变量,这也是 C++ 对作用域和变量生命周期的保证。
通过捕获列表,C++ 保证了 lambda 的作用域不会无意中影响外部变量的生命周期,从而避免了潜在的错误和副作用。
原文地址:https://blog.csdn.net/u013798595/article/details/144208797
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!