Maison >développement back-end >C++ >Comment puis-je réaliser une capture de mouvement dans C Lambdas (C 11 et C 14) ?
C 14 introduit la capture lambda généralisée, permettant la capture de mouvement. En C 14, un code comme celui-ci sera valide :
auto u = make_unique<some_type>( some, parameters ); // move the unique_ptr into the lambda go.run( [ u = move(u) ] { do_something_with( u ); } );
Notez que si vous devez déplacer l'objet du lambda vers une autre fonction, le lambda doit être marqué comme mutable :
go.run( [ u = move(u) ] mutable { do_something_with( std::move(u) ); } );
En C 11, la capture par mouvement peut être réalisée à l'aide d'une fonction d'assistance make_rref qui crée une référence rvalue à la valeur souhaitée :
#include <cassert> #include <memory> #include <utility> template <typename T> struct rref_impl { rref_impl() = delete; rref_impl( T && x ) : x{std::move(x)} {} // ... implementation }; template<typename T> rref_impl<T> make_rref( T && x ) { return rref_impl<T>{ std::move(x) }; }
Utilisez la fonction make_rref pour capturer la valeur dans le lambda :
int main() { std::unique_ptr<int> p{new int(0)}; auto rref = make_rref( std::move(p) ); auto lambda = [rref]() mutable -> std::unique_ptr<int> { return rref.move(); }; assert( lambda() ); assert( !lambda() ); }
Notez que cette solution de contournement rend le lambda copiable, ce qui peut causer des problèmes lors de la capture d'objets non copiables.
Une autre approche pour émuler la capture lambda généralisée consiste à définir une fonction de capture :
#include <utility> template <typename T, typename F> class capture_impl { T x; F f; public: // ... 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) ); }
Utiliser la capture pour capturer la valeur par déplacement :
int main() { std::unique_ptr<int> p{new int(0)}; auto lambda = capture( std::move(p), []( std::unique_ptr<int> & p ) { return std::move(p); } ); assert( lambda() ); assert( !lambda() ); }
Cette solution fournit une approche plus propre qui désactive la copie du lambda si le type capturé n'est pas copiable.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!