Maison > développement back-end > C++ > Comment implémenter Move Capture dans C Lambdas ?

Comment implémenter Move Capture dans C Lambdas ?

Linda Hamilton
Libérer: 2024-12-26 13:35:10
original
786 Les gens l'ont consulté

How to Implement Move Capture in C   Lambdas?

Capture de mouvement dans Lambdas

Question :

Comment implémenter la capture de mouvement, également connues sous le nom de références rvalue, en C 11 lambdas ? Par exemple :

std::unique_ptr<int> myPointer(new int);

std::function<void(void)> example = [std::move(myPointer)] {
   *myPointer = 4;
};
Copier après la connexion

Réponse :

Capture Lambda généralisée en C 14

En C 14, lambda généralisée la capture permet la capture de mouvements. Ce code est désormais valide :

using namespace std;

auto u = make_unique<some_type>(some, parameters);  
go.run([u = move(u)] { do_something_with(u); }); 
Copier après la connexion

Pour déplacer des objets d'un lambda vers une autre fonction, rendez le lambda mutable :

go.run([u = move(u)] mutable { do_something_with(std::move(u)); });
Copier après la connexion

Solution de contournement pour Move Capture en C 11

Une fonction d'assistance, make_rref, peut faciliter la capture de mouvements. Son implémentation est la suivante :

#include <cassert>
#include <memory>
#include <utility>

template <typename T>
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<typename T> rref_impl<T> make_rref(T&& x) {
    return rref_impl<T>{std::move(x)};
}
Copier après la connexion

Un cas de test pour make_rref :

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());
}
Copier après la connexion

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

Un autre une solution de contournement est fournie par la fonction capture() :

#include <cassert>
#include <memory>

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());
}
Copier après la connexion

la capture est implémentée comme suit :

#include <utility>

template <typename T, typename F>
class capture_impl {
    T x;
    F f;
public:
    capture_impl(T&& x, F&& f)
        : x{std::forward<T>(x)}, f{std::forward<F>(f)} {}

    template <typename ...Ts> auto operator()(Ts&& ...args)
        -> decltype(f(x, std::forward<Ts>(args)...)) {
        return f(x, std::forward<Ts>(args)...);
    }

    template <typename ...Ts> auto operator()(Ts&& ...args) const
        -> decltype(f(x, std::forward<Ts>(args)...)) {
        return f(x, std::forward<Ts>(args)...);
    }
};

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));
}
Copier après la connexion

Cette solution empêche la copie du lambda si le type capturé n'est pas copiable, évitant ainsi les erreurs d'exécution.

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!

source:php.cn
Déclaration de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal