0
votes

Existe-t-il un but de déclarer Lambda suivi de l'invocation immédiate pour initialiser la variable locale en utilisant sa valeur de retour?

template<typename T>
    static const Metatype* get_metatype() {
        static const Metatype* mt = []() {
            constexpr size_t name_hash = Metatype::build_hash<T>().name_hash;

            auto type = metatype_cache.find(name_hash);
            if (type == metatype_cache.end()) {
                constexpr Metatype newtype = Metatype::build<T>();
                metatype_cache[name_hash] = newtype;
            }
            return &metatype_cache[name_hash];
        }();
        return mt;
    }
Variable mt initialized by lambda's return value. Why not just extract lambda code and make it part of get_metatype() function then just return value from it?  Is this some performance trick or what?? This code from decs https://github.com/vblanco20-1/decs project that i am learning for educational purposes.

0 commentaires

3 Réponses :


1
votes

Ceci est couramment utilisé pour initialiser une variable qui doit être const , mais est également complexe à initialiser. par exemple xxx

sans faire cela, il n'y a pas de bon moyen de faire v const .

Cependant, dans votre Le cas, la raison de l'utilisation de cette technique dans l'exemple fourni, est de sorte que la variable statique MT n'est pas intitulée sur chaque appel à get_metatype , comme indiqué par @walnut, et @remylebeau.


2 commentaires

@Cigien no, MT est un point de pointeur non-const à un objet constype objet, ce n'est pas un const Pointeur sur un objet.


J'ai édité la réponse pour ajouter la raison d'initialisation statique. Merci beaucoup.



1
votes

En plus de ce que @Cigien a dit - une variable statique est initialisée une seule fois. C ++ 11 et plus tard, assurez-vous que l'initialisation est effectuée de manière thread-sûre. L'utilisation d'une lambda pour l'initialiszer garantit que la Lambda n'est appelée qu'une seule fois. Si vous deviez entrer en ligne le code de Lambda directement dans get_metatype () , vous seriez responsable de la sérialisation manuelle du code vous-même, par exemple avec un mutex.


0 commentaires

1
votes

La variable MT est déclarée statique , ce qui signifie qu'une seule instance (avec durée de stockage statique) de MT pour chaque T dans le programme ou dans chaque unité de traduction (selon que la fonction affichée est une fonction statique dans une classe ou à la portée des espaces de noms) et si la fonction get_metatype () est appelé plusieurs fois dans le programme, seul le premier appel d'accès à la déclaration MT exécutera initialisateur MT et initialiser mt . Les autres appels renverront simplement la valeur fixe de MT . Ceci est même garanti de maintenir lorsque plusieurs threads sont impliqués, sans que l'initialiseur soit appelé dans deux des fils.

Utilisation d'un Lambda directement invoqué dans l'initialiszer permet de mettre tout le code qui doit être exécuté une fois pour initialiser la variable MT dans un endroit en ligne sans avoir à créer une nouvelle fonction pour cela. . Si vous mettez les énoncés à l'intérieur de la Lambda directement dans le corps de get_metatype () , ils seraient exécutés chaque la fonction est appelée et non seulement une fois, et la responsabilité d'éviter les courses de données dans l'initialisation lorsque plusieurs threads sont impliqués se déplaceraient vers vous.

En particulier, les raisons possibles de l'utilisation du statique MT peuvent être qu'il existe plusieurs threads et une course de données sur la construction du "MetaType" doit être évité, bien qu'il semblerait encore d'être une condition de course ou même une course de données sur métataype_cache si plusieurs appels vers get_metatype () pour différents T < / code> sont fabriqués, car le trouver et le placement dans le conteneur ne sont pas effectués atomiquement.

ou une raison possible pourrait être que les opérations de recherche dans get_metatype prenez trop longtemps pour exécuter chaque fois get_metatype est appelé, bien qu'un statique La variable n'est pas le meilleur choix pour l'optimisation des performances non plus, car elle nécessite des chèques de fil-sécurité sur chaque appel pour vérifier si MT a déjà été initialisé.


0 commentaires