Kann jemand beschreiben, warum dieser Code nicht funktioniert (auf GCC4.7.3 seg-Fehler vor der Rückkehr von Anruf)?Speicherverwaltung für 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 ;
};
Meine ursprünglichen Annahmen:
- jede
std::function<T()>
irgendwie ist Referenz/shared_ptr auf ein Objekt, das Verschluss darstellt. I.e. die Lebensdauer des aufgenommenen Wertes ist dadurch begrenzt. std::function<T()>
Objekt Zuweisungsoperator, der die alte Schließung aufgibt (Ende der Lebensdauer ausgewählt Werte) und wird Besitz für einen neuen Wert übernehmen.
P.S. Diese Frage aufgeworfen, nachdem ich question about lazy in C++11
Hm, irgendwie 'thunk_ptr' landet selbst zu besitzen. Das scheint nicht richtig zu sein. –
@KerrekSB, ja, stimme zu, aber das sollte Speicher-Leck statt Seg-Fehler – ony
bekommen Der Grund hinter 'return (* thunk_ptr)();' ist die Referenz auf das Feld der Schließung zurückgeben '[val]() {return val; } 'wenn Referenzen zu' thunk_type' hinzugefügt werden. Siehe (alternative Implementierung von 'faul' in meiner Antwort) [http://stackoverflow.com/a/19125422/230744] – ony