Maison > développement back-end > C++ > le corps du texte

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

Susan Sarandon
Libérer: 2024-10-29 13:20:02
original
374 Les gens l'ont consulté

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

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

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!

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