Qualcuno potrebbe descrivere il motivo per cui questo codice non funziona (su GCC4.7.3 errori di segmento prima di tornare dalla chiamata)?gestione della memoria per lambda in C++ 11
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
template<typename F>
auto memo(const F &x) -> std::function<decltype(x())()> {
typedef decltype(x()) return_type;
typedef std::function<return_type()> thunk_type;
std::shared_ptr<thunk_type> thunk_ptr = std::make_shared<thunk_type>();
*thunk_ptr = [thunk_ptr, &x]() {
cerr << "First " << thunk_ptr.get() << endl;
auto val = x();
*thunk_ptr = [val]() { return val; };
return (*thunk_ptr)();
};
return [thunk_ptr]() { return (*thunk_ptr)(); };
};
int foo() {
cerr << "Hi" << endl;
return 42;
}
int main() {
auto x = memo(foo);
cout << x() << endl ;
cout << x() << endl ;
cout << x() << endl ;
};
mie ipotesi originali:
- ogni
std::function<T()>
è un pò riferimento/shared_ptr a qualche oggetto che rappresenta la chiusura. Cioè il tempo di vita del valore prelevato è limitato da esso. std::function<T()>
l'oggetto ha un operatore di assegnazione che abbandonerà la chiusura precedente (termina i valori di durata di vita selezionati) e assumerà la proprietà di un nuovo valore.
P.S. Questa domanda ha sollevato dopo aver letto question about lazy in C++11
Hm, in qualche modo 'thunk_ptr' finisce per possedere in sé. Non sembra giusto. –
@KerrekSB, sì, d'accordo, ma questo dovrebbe ottenere perdite di memoria piuttosto che seg-fault – ony
Il motivo alla base di 'return (* thunk_ptr)();' è di restituire riferimento al campo di chiusura '[val]() {return val; } 'se i riferimenti vengono aggiunti a' thunk_type'. Vedi (implementazione alternativa di 'pigro' nella mia risposta) [http://stackoverflow.com/a/19125422/230744] – ony