我已经将代码简化为仍然存在问题的最小样本。此代码应打印" 42",而是打印不同的数字。我还打印了#34; Secret"的地址。析构函数中的对象,当访问它时,表明它被过早地破坏了。我在这里做错了什么,或者这可能是编译器的问题?
代码:
#include <iostream>
using namespace std;
struct Secret{
int value;
Secret(int value):value(value){}
~Secret(){
cout<<"destructor:"<<(void*)this<<endl;
value=0;
}
};
template<class Func>
class Copier{
public:
Func func;
Copier(Func func):func(func){}
void run(){
func();
}
auto copy(){
auto output = [this](){
func();
};
Copier<decltype(output)> out(output);
return out;
}
};
auto makeSecretPrinter(){
Secret secret(42);
auto secretPrinter = [secret](){
cout<<"reading object at address:"<<(void*)&secret<<endl;
cout<<"the secret is:"<<secret.value<<endl;
};
return Copier<decltype(secretPrinter)>(secretPrinter).copy();
}
int main(){
makeSecretPrinter().run();
return 0;
}
clang(版本3.5-1ubuntu1)输出:
destructor:0x7fff9e3f9940
destructor:0x7fff9e3f9938
destructor:0x7fff9e3f9948
destructor:0x7fff9e3f9950
reading object at address:0x7fff9e3f9940
the secret is:0
GCC(Ubuntu 4.9.2-0ubuntu1~14.04)4.9.2输出:
destructor:0x7fff374facc0
destructor:0x7fff374facb0
destructor:0x7fff374faca0
destructor:0x7fff374fac90
reading object at address:0x7fff374facc0
the secret is:-1711045632
答案 0 :(得分:3)
使用指针语义捕获this
捕获。改变这个:
auto output = [this](){
func();
};
解决了这个问题:
auto output = [self=*this](){
self.func();
};
答案 1 :(得分:0)
行:makeSecretPrinter().run()
,它实际上先执行makeSecretPrinter()
,然后执行run()
。但是,当run()
正在执行时,它已经超出了makeSecretPrinter()
的范围。因此,lambda函数没有得到正确的值作为要调用的参数。
请注意,您的类仅接收函数指针(或函数引用,它们在语义上是相同的。)这意味着该值不会传递到Copier
类。当Copier
尝试'run()'时,它需要在makeSecretPrinter()
中拾取变量。但是,正如我所说,当'run()'被执行时,它超出了范围。