如何解决为什么lambda通过引用捕获仍可与悬空引用一起使用?
令我惊讶的是,以下C ++程序:
#include <iostream>
#include <functional>
int main() {
std::function<void(void)> f;
{
int x = 1;
f = [&x]() { std::cout << x; };
}
//std::cout << x; // error: use of undeclared identifier 'x'
f(); // no error!
return 0;
}
输出:
1
与取消注释行时,我期望获得与输出相同的输出:
error: use of undeclared identifier 'x'
因为lambda f
通过引用捕获了自动变量x
(不是 by value ),并且x
不在调用点f()
的上下文(因此x
主体中的f
是一个悬空引用)。
为什么通过引用捕获lambda仍可与悬挂的引用一起使用?
解决方法
它不起作用。这只是它显示1的一个巧合。恰好是在调用lambda时,它驻留在捕获的地址中的某个值可以解释为带值1的int类型。
lambda的生存期大于变量的生存期。变量x在右花括号处被破坏,但是lambda仍然保留对其的引用。任何访问该引用的尝试都会导致未定义的行为。
在lambda声明中,您告诉要捕获的内容。使用声明它的地方的当前范围。调用lambda时,您告诉何时进行捕获。因此,与您的问题中的参考文献相比,它可以进行编译。但是,您有责任提供所使用变量的正确生命周期。
,为什么lambda通过引用捕获仍可与悬空引用一起使用?
这是未定义的行为,因此可能有任何原因说明其工作方式。如果您使用以下代码编译代码:
在这里尝试:https://godbolt.org/z/5dd5sM
clang++ -O3 -fsanitize=address
您将立即获得:
ERROR: AddressSanitizer: stack-use-after-scope on address ....
READ of size 4...
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。