Maison  >  Article  >  développement back-end  >  Comment les expressions Lambda C 11 peuvent-elles être utilisées pour implémenter des gardes de portée ?

Comment les expressions Lambda C 11 peuvent-elles être utilisées pour implémenter des gardes de portée ?

Susan Sarandon
Susan Sarandonoriginal
2024-10-29 13:20:02306parcourir

How can C  11 Lambda Expressions be Used to Implement Scope Guards?

Scope Guards en C 11

L'un des principaux avantages des expressions lambda C 11 réside dans leur capacité à exprimer le concept de RAII ( L'acquisition de ressources est l'initialisation) de manière concise et élégante. L'implémentation traditionnelle de RAII s'appuie sur des destructeurs pour libérer les ressources, mais avec les expressions lambda, il est possible de créer un objet qui exécutera une fonction de nettoyage en quittant sa portée, quelle que soit la manière dont cette sortie se produit. C'est ce qu'on appelle un scope guard.

Implémentation simple de Scope Guard

Voici un exemple d'implémentation simple de Scope Guard en C 11 :

<code class="c++">template< typename Lambda >
class ScopeGuard
{
    mutable bool committed;
    Lambda rollbackLambda;
    public:

        ScopeGuard( const Lambda&amp; _l) : committed(false) , rollbackLambda(_l) {}

        template< typename AdquireLambda >
        ScopeGuard( const AdquireLambda&amp; _al , const Lambda&amp; _l) : committed(false) , rollbackLambda(_l)
        {
            _al();
        }

        ~ScopeGuard()
        {
            if (!committed)
                rollbackLambda();
        }
        inline void commit() const { committed = true; }
};</code>

La classe ScopeGuard prend une expression lambda comme argument constructeur, qui représente l'action de nettoyage à exécuter lorsque le scope guard sort de la portée. L'indicateur commit indique si l'action de nettoyage a été exécutée.

Utilisation

La classe ScopeGuard peut être utilisée pour garantir que les ressources sont libérées correctement, même si une exception se produit . Par exemple, la fonction suivante acquiert une ressource et s'assure qu'elle est libérée à l'aide d'un scope guard :

<code class="c++">void SomeFuncThatShouldBehaveAtomicallyInCaseOfExceptions() 
{
    std::vector<int> myVec;
    std::vector<int> someOtherVec;

    myVec.push_back(5);
    //first constructor, adquire happens elsewhere
    const auto&amp; a = RAII::makeScopeGuard( [&amp;]() { myVec.pop_back(); } );  

    //sintactically neater, since everything happens in a single line
    const auto&amp; b = RAII::makeScopeGuard( [&amp;]() { someOtherVec.push_back(42); }
                     , [&amp;]() { someOtherVec.pop_back(); } ); 

    b.commit();
    a.commit();
}</code>

Dans cet exemple, le ScopeGuard est utilisé pour garantir que les éléments sont supprimés des vecteurs même si un une exception se produit.

Conclusion

Les gardes de portée sont un outil puissant pour garantir que les ressources sont correctement libérées dans C 11. La mise en œuvre simple présentée ici est un moyen simple de mettre en œuvre ce modèle. Cependant, il existe des implémentations plus complexes qui offrent des fonctionnalités supplémentaires, telles que la possibilité de transférer la propriété des ressources entre les gardes de portée.

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