Maison >développement back-end >C++ >Comment puis-je réaliser une capture de mouvement dans C Lambdas (C 11 et C 14) ?

Comment puis-je réaliser une capture de mouvement dans C Lambdas (C 11 et C 14) ?

Barbara Streisand
Barbara Streisandoriginal
2024-12-17 20:56:12805parcourir

How Can I Achieve Move Capture in C   Lambdas (C  11 and C  14)?

Capture de mouvement en C 11 Lambda

Capture Lambda généralisée en 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) ); } );

Solution de contournement pour la capture de mouvement en C 11

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 &amp;&amp; x ) : x{std::move(x)} {}
    // ... implementation
};

template<typename T> rref_impl<T> make_rref( T &amp;&amp; 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.

Émulation de la capture Lambda généralisée en C 11

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 &amp;&amp; x, F &amp;&amp; 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> &amp; 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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn