Einführung
In C ist die Erfassung durch Bewegung, auch R-Wert-Referenz genannt, möglich für die effiziente Übertragung des Besitzes eines Objekts auf einen Lambda-Ausdruck. Diese Technik kann besonders in Situationen nützlich sein, in denen die Ressourcen des Objekts explizit innerhalb des Lambda verwaltet werden müssen.
In C 14 bietet die verallgemeinerte Lambda-Erfassung eine elegante Lösung zur Bewegungserfassung. Mit dieser Funktion ist es möglich, einen Lambda-Ausdruck zu deklarieren, der eine Variable nach Wert mithilfe der Verschiebungssemantik erfasst:
using namespace std; auto u = make_unique<some_type>(some, parameters); go.run([u = move(u)] { do_something_with(u); });
Dieser Ansatz verschiebt den Besitz von u in das Lambda und stellt so sicher, dass die Ressourcen ordnungsgemäß freigegeben werden. Wenn das Objekt außerdem aus dem Lambda verschoben werden muss, muss das Lambda als veränderlich deklariert werden.
In C 11 erfolgt die Move Capture nicht direkt unterstützt. Es gibt jedoch Techniken, die dieses Verhalten nachahmen können. Ein Ansatz besteht darin, eine Hilfsfunktion zu verwenden, um eine R-Wert-Referenz (rref) zu erstellen:
template <typename T> struct rref_impl { rref_impl() = delete; rref_impl(T &&x) : x(std::move(x)) {} // ... (remaining implementation) }; template<typename T> rref_impl<T> make_rref(T &&x) { return rref_impl<T>{std::move(x)}; }
Mit dieser Hilfsfunktion ist es möglich, ein Objekt durch Verschieben in einem Lambda zu erfassen:
unique_ptr<int> p{new int(0)}; auto rref = make_rref(std::move(p)); auto lambda = [rref]() mutable -> unique_ptr<int> { return rref.move(); };
Beachten Sie, dass das Lambda als veränderlich deklariert ist, um die Änderung der erfassten R-Wert-Referenz zu ermöglichen.
Ein weiterer Ansatz zur Emulation der verallgemeinerten Lambda-Erfassung in C 11 besteht darin, eine benutzerdefinierte Klasse zu verwenden, um eine Variable zu erfassen und eine Möglichkeit bereitzustellen, sie aus dem Lambda zu verschieben:
template <typename T, typename F> struct capture_impl { T x; F f; // ... (remaining implementation) }; template <typename T, typename F> capture_impl<T,F> capture(T &&x, F &&f) { return capture_impl<T,F>(std::forward<T>(x), std::forward<F>(f)); }
Diese Klasse kann verwendet werden, um eine Variable durch Verschieben zu erfassen und eine Möglichkeit zum Aufrufen des Lambda bereitzustellen:
unique_ptr<int> p{new int(0)}; auto lambda = capture(std::move(p), [](unique_ptr<int> &p) { return std::move(p); });
Im Gegensatz zum vorherigen Ansatz ist dies Lambda ist nicht kopierbar, wenn der erfasste Typ nicht kopierbar ist. Dies verhindert mögliche Fehler beim Kopieren des Lambda.
Das obige ist der detaillierte Inhalt vonWie kann ich Objekte durch Verschieben in C-Lambda-Ausdrücken effizient erfassen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!