我试图弄清楚lambda是如何在C++中工作的。
奇怪的事情发生了。太奇怪了,我不知道怎么正确地描述它。我试过搜索几个关键词,但没有发现任何提到这种行为的东西。
我第一次尝试了这段代码。
#include <iostream>
#include <utility>
using namespace std ;
auto func() {
int a = 0 ;
auto increase = [ &a ]( int i = 1 ){ a += i ; } ;
auto print = [ &a ](){ cout << a << '\n' ; } ;
pair< decltype(increase), decltype(print) >
p = make_pair( increase, print ) ;
return p ;
}
int main() {
auto lambdas = func() ;
auto increase = lambdas.first ;
auto print = lambdas.second ;
print() ;
increase() ;
print() ;
increase( 123456 ) ;
print() ;
return 0;
}输出与预期的相同
-1218965939
-1218965938
-1218842482但是,在我将它添加到'func()‘之后
cout << typeid( decltype( print ) ).name() << '\n'
<< typeid( decltype( increase ) ).name() << '\n' ;就像这一个
输出变成
Z4funcvEUlvE0_
Z4funcvEUliE_
0
1
123457我没想到会发生。
更新
变量a应该是“死的”,因为它的生命周期已经结束了。
但我很好奇为什么typeid和decltype的代码测试似乎会使a复活呢?
发布于 2016-05-16 23:17:06
纯机会.
我怀疑您知道,您正在通过一个悬空引用打印未指定的值。
cout**s和/或** typeid**s已经影响了编译程序实现的血淋淋的内脏**,因此在非法打印a值时,a的内存位置恰好没有受到影响。但是,试图进一步理顺这一点是没有意义的,下次运行该程序时,您可能会得到一个不同的结果。否则你的电脑就会爆炸。或者时间线可以被改变,以至于你从未出生过。不要试图解释UB的症状--只是避免它。
发布于 2016-05-16 23:12:38
您的程序的输出没有一个是“预期的”。
func()中的lambda通过引用捕获一个本地范围的变量,一旦func()返回,该变量就会超出作用域。
func()返回后,a不再存在,就像任何其他函数--本地作用域对象一样。因此,它们捕获的引用现在被引用到超出作用域并被销毁的对象,而引用值的任何使用都成为未定义的行为。
更糟糕的是,代码还通过无效引用来设置值.在传统的实现中,这将在堆栈的一些随机部分上乱写,这可能导致整个流程崩溃。
https://stackoverflow.com/questions/37264608
复制相似问题