J'essaie de comprendre comment obtenir l'adresse d'une fonction lambda en elle-même. Voici un exemple de code:
[]() {
std::cout << "Address of this lambda function is => " << ????
}();
Je sais que je peux capturer le lambda dans une variable et imprimer l'adresse, mais je veux le faire en place lorsque cette fonction anonyme s'exécute.
Existe-t-il un moyen plus simple de le faire?
this
.Réponses:
Ce n'est pas directement possible.
Cependant, les captures lambda sont des classes et l'adresse d'un objet coïncide avec l'adresse de son premier membre. Par conséquent, si vous capturez un objet par valeur comme première capture, l'adresse de la première capture correspond à l'adresse de l'objet lambda:
Les sorties:
Vous pouvez également créer un modèle de conception de décorateur lambda qui transmet la référence à la capture lambda à son opérateur d'appel:
la source
Il n'y a aucun moyen d'obtenir directement l'adresse d'un objet lambda dans un lambda.
Maintenant, comme cela arrive, cela est très souvent utile. L'usage le plus courant est pour soigner.
Le
y_combinator
vient de langues où vous ne pouviez pas parler de vous jusqu'à ce que vous soyez défini. Il peut être implémenté assez facilement en c ++ :vous pouvez maintenant le faire:
Une variation de ceci peut inclure:
où le
self
passé peut être appelé sans passerself
comme premier argument.Le second correspond au vrai combinateur y (aka le combinateur à virgule fixe) je crois. Ce que vous voulez dépend de ce que vous entendez par «adresse de lambda».
la source
F
n'est pas une disposition standard, cey_combinator
n'est pas le cas, donc les garanties raisonnables ne sont pas fournies.Une façon de résoudre ce problème serait de remplacer le lambda par une classe de foncteurs manuscrite. C'est aussi ce que la lambda est essentiellement sous le capot.
Ensuite, vous pouvez obtenir l'adresse
this
, même sans jamais affecter le foncteur à une variable:Cela a l'avantage d'être 100% portable et extrêmement facile à raisonner et à comprendre.
la source
struct { void operator()() { std::cout << "Address of this functor is => " << this << '\n'; } } f;
Capturez le lambda:
la source
std::function
n'est cependant pas nécessaire ici, et cela a un coût considérable. De plus, copier / déplacer cet objet le cassera.C'est possible mais dépend fortement de la plateforme et de l'optimisation du compilateur.
Sur la plupart des architectures que je connais, il existe un registre appelé pointeur d'instruction. Le point de cette solution est de l'extraire lorsque nous sommes à l'intérieur de la fonction.
Sur amd64 Le code suivant devrait vous donner des adresses proches de celle de la fonction.
Mais par exemple sur gcc https://godbolt.org/z/dQXmHm avec la
-O3
fonction de niveau d'optimisation peut être intégrée.la source
thread_local
durée automatique ou de stockage. Ce que vous essayez d'obtenir ici, c'est l'adresse de retour de la fonction, pas un objet. Mais même cela ne fonctionnera pas car le prologue de la fonction générée par le compilateur pousse vers la pile et ajuste le pointeur de la pile pour faire de la place aux variables locales.