Maison >développement back-end >C++ >Comment puis-je capturer efficacement des objets en les déplaçant dans des expressions C Lambda ?

Comment puis-je capturer efficacement des objets en les déplaçant dans des expressions C Lambda ?

DDD
DDDoriginal
2024-12-09 07:19:07719parcourir

How Can I Efficiently Capture Objects by Move in C   Lambda Expressions?

Capture de déplacement dans les expressions Lambda

Introduction

En C, la capture par déplacement, également appelée référence rvalue, permet pour le transfert efficace de la propriété d'un objet vers une expression lambda. Cette technique peut être particulièrement utile dans les situations où les ressources de l'objet doivent être gérées explicitement dans le lambda.

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

En C 14, la capture lambda généralisée offre une solution élégante pour la capture de mouvements. Avec cette fonctionnalité, il est possible de déclarer une expression lambda qui capture une variable par valeur en utilisant la sémantique de déplacement :

using namespace std;

auto u = make_unique<some_type>(some, parameters);  

go.run([u = move(u)] { do_something_with(u); });

Cette approche déplace la propriété de u dans le lambda, garantissant que les ressources sont libérées de manière appropriée. De plus, si l'objet doit être déplacé hors du lambda, le lambda doit être déclaré comme mutable.

Solution de contournement pour Move Capture en C 11

En C 11, la capture de déplacement n'est pas directement soutenu. Il existe cependant des techniques permettant d’imiter ce comportement. Une approche consiste à utiliser une fonction d'assistance pour créer une référence rvalue (rref) :

template <typename T>
struct rref_impl {
    rref_impl() = delete;
    rref_impl(T &&x) : x(std::move(x)) {}
    // ... (remaining implementation)
};

template<typename T> rref_impl<T> make_rref(T &&x) {
    return rref_impl<T>{std::move(x)};
}

En utilisant cette fonction d'assistance, il est possible de capturer un objet par déplacement dans un lambda :

unique_ptr<int> p{new int(0)};
auto rref = make_rref(std::move(p));
auto lambda = [rref]() mutable -> unique_ptr<int> { return rref.move(); };

Notez que le lambda est déclaré comme mutable pour permettre la modification de la référence rvalue capturée.

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

Une autre approche pour émuler la capture lambda généralisée en C 11 consiste à utiliser une classe personnalisée pour capturer une variable et fournir un moyen de la déplacer hors du lambda :

template <typename T, typename F>
struct capture_impl {
    T x;
    F f;
    // ... (remaining 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));
}

Cette classe peut être utilisé pour capturer une variable par déplacement et fournir un moyen d'invoquer le lambda :

unique_ptr<int> p{new int(0)};
auto lambda = capture(std::move(p), [](unique_ptr<int> &p) { return std::move(p); });

Contrairement à l'approche précédente, cette lambda n'est pas copiable, si le type capturé n'est pas copiable. Cela évite des erreurs potentielles lors de la copie du lambda.

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