"Si un ouvrier veut bien faire son travail, il doit d'abord affûter ses outils." - Confucius, "Les Entretiens de Confucius. Lu Linggong"
Page de garde > La programmation > Conseils d'implémentation de capture mobile dans C ++ Lambda

Conseils d'implémentation de capture mobile dans C ++ Lambda

Publié le 2025-04-12
Parcourir:429

How to Implement Move Capture in C   Lambdas?

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_ptr myPointer(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_ptr p{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:

#include 

template 
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.

Dernier tutoriel Plus>

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