Déplacer la capture en lambdas
Question:
Comment mettre en œuvre la capture de déplacement, également connue sous le nom de références RValue, dans C 11 Lambdas? Par exemple:
std::unique_ptrmyPointer(new int); std::function example = [std::move(myPointer)] { *myPointer = 4; };
Réponse:
Capture de lambda généralisée en C 14
En C 14, la capture de lambda généralisée permet la capture de mouvement. Ce code est maintenant valide:
using namespace std; auto u = make_unique(some, parameters); go.run([u = move(u)] { do_something_with(u); });
pour déplacer des objets d'un lambda à une autre fonction, rendre le lambda mutable:
go.run([u = move(u)] mutable { do_something_with(std::move(u)); });
11
une fonction d'assistance, make_rref, peut faciliter la capture de déplacement. Son implémentation est la suivante:
#include#include #include template struct rref_impl { rref_impl() = delete; rref_impl(T&& x) : x{std::move(x)} {} rref_impl(rref_impl& other) : x{std::move(other.x)}, isCopied{true} { assert(other.isCopied == false); } rref_impl(rref_impl&& other) : x{std::move(other.x)}, isCopied{std::move(other.isCopied)} { } rref_impl& operator=(rref_impl other) = delete; T& operator&&() { return std::move(x); } private: T x; bool isCopied = false; }; template rref_impl make_rref(T&& x) { return rref_impl {std::move(x)}; }
un cas de test pour Make_rref:
int main() { std::unique_ptrp{new int(0)}; auto rref = make_rref(std::move(p)); auto lambda = [rref]() mutable -> std::unique_ptr { return rref.move(); }; assert(lambda()); assert(!lambda()); }
émulant la capture de lambda généralisée en c 11
Une autre solution de contournement est fournie par la fonction capture ():
#include#include int main() { std::unique_ptr p{new int(0)}; auto lambda = capture(std::move(p), [](std::unique_ptr & p) { return std::move(p); }); assert(lambda()); assert(!lambda()); }
capture est implémenté comme suit:
#includetemplate class capture_impl { T x; F f; public: capture_impl(T&& x, F&& f) : x{std::forward (x)}, f{std::forward (f)} {} template auto operator()(Ts&& ...args) -> decltype(f(x, std::forward (args)...)) { return f(x, std::forward (args)...); } template auto operator()(Ts&& ...args) const -> decltype(f(x, std::forward (args)...)) { return f(x, std::forward (args)...); } }; template capture_impl capture(T&& x, F&& f) { return capture_impl ( std::forward (x), std::forward (f)); }
Cette solution empêche la copie du Lambda si le type capturé n'est pas copieable, évitant les erreurs d'exécution.
Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.
Copyright© 2022 湘ICP备2022001581号-3