코드를 여전히 문제가있는 가장 작은 샘플로 단순화했습니다. 이 코드는 "42"를 인쇄해야하지만 대신 다른 번호를 인쇄합니다. 또한 소멸자에서 "Secret"개체의 주소를 인쇄하고 액세스 할 때 너무 일찍 소멸되었음을 보여줍니다. 내가 여기서 뭔가 잘못하고있는 중이거나 컴파일러에 문제가있을 수 있습니까?C++ 소멸자가 너무 일찍 호출 됨
코드 :
#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;
}
그 소리 (버전 3.5-1ubuntu1) 출력 :
destructor:0x7fff9e3f9940
destructor:0x7fff9e3f9938
destructor:0x7fff9e3f9948
destructor:0x7fff9e3f9950
reading object at address:0x7fff9e3f9940
the secret is:0
GCC (우분투 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
'this'캡처는 포인터 의미론으로 캡처하는 것을 의미합니다. 캡처 된 객체가 파괴되면, 포인터를 역 참조 할 수 없습니다 ('copy'의'output' 람다에서와 같이 암시 적으로조차하지 않습니다). 그 람다를 복사하는 것은 캡쳐 된 포인터를 복사하는데, 즉 얕은 복사를 수행한다. – dyp
'auto output = [this]() {'이 줄은 문제가있는 것처럼 보입니다. 포인터 대신'* this'를 복사하고 싶습니다. –
@BryanChen 정확히 내가 생각한 것 : http://coliru.stacked-crooked.com/a/43b70f00c4a20469 – dyp