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.
3 Réponses :
Ceci est couramment utilisé pour initialiser une variable qui doit être sans faire cela, il n'y a pas de bon moyen de faire Cependant, dans votre Le cas, la raison de l'utilisation de cette technique dans l'exemple fourni, est de sorte que la variable statique const code>, mais est également complexe à initialiser. par exemple
v code>
const code>. p>
MT code> n'est pas intitulée sur chaque appel à
get_metatype code>, comme indiqué par @walnut, et @remylebeau. P> p>
@Cigien no, MT code> est un point de pointeur non-const b> à un objet code> constype code> objet, ce n'est pas un const b > Pointeur sur un objet.
J'ai édité la réponse pour ajouter la raison d'initialisation statique. Merci beaucoup.
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 () code>, vous seriez responsable de la sérialisation manuelle du code vous-même, par exemple avec un mutex. P>
La variable 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 En particulier, les raisons possibles de l'utilisation du ou une raison possible pourrait être que les opérations de recherche dans MT code> est déclarée
statique code>, ce qui signifie qu'une seule instance (avec durée de stockage statique) de
MT code> pour chaque
T code> dans le programme ou dans chaque unité de traduction (selon que la fonction affichée est une fonction code> statique code> dans une classe ou à la portée des espaces de noms) et si la fonction
get_metatype
MT code> exécutera
initialisateur MT code> et initialiser
mt code>. Les autres appels renverront simplement la valeur fixe de
MT code>. Ceci est même garanti de maintenir lorsque plusieurs threads sont impliqués, sans que l'initialiseur soit appelé dans deux des fils. P>
MT code> 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
statique code>
MT code> 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 code> si plusieurs appels vers
get_metatype
T < / code> sont fabriqués, car le
trouver code> et le placement dans le conteneur ne sont pas effectués atomiquement. P>
get_metatype code> prenez trop longtemps pour exécuter chaque fois
get_metatype code> est appelé, bien qu'un
statique code> 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 code> a déjà été initialisé. P>