Estoy tratando de descubrir cómo obtener la dirección de una función lambda dentro de sí misma. Aquí hay un código de muestra:
[]() {
std::cout << "Address of this lambda function is => " << ????
}();
Sé que puedo capturar el lambda en una variable e imprimir la dirección, pero quiero hacerlo en el lugar cuando se ejecuta esta función anónima.
¿Hay una manera más simple de hacerlo?
this
.Respuestas:
No es directamente posible.
Sin embargo, las capturas lambda son clases y la dirección de un objeto coincide con la dirección de su primer miembro. Por lo tanto, si captura un objeto por valor como la primera captura, la dirección de la primera captura corresponde a la dirección del objeto lambda:
Salidas:
Alternativamente, puede crear un patrón de diseño de decorador lambda que pase la referencia a la captura lambda a su operador de llamada:
fuente
No hay forma de obtener directamente la dirección de un objeto lambda dentro de una lambda.
Ahora, como sucede, esto es bastante útil. El uso más común es para recurrir.
El
y_combinator
proviene de idiomas donde no se podía hablar de uno mismo hasta que la defina. Se puede implementar con bastante facilidad en c ++ :ahora puedes hacer esto:
Una variación de esto puede incluir:
donde
self
se puede llamar al pasado sin pasarself
como primer argumento.El segundo coincide con el combinador y real (también conocido como el combinador de punto fijo), creo. Lo que desea depende de lo que quiere decir con "dirección de lambda".
fuente
F
no es un diseño estándar, entoncesy_combinator
no lo es, por lo que no se proporcionan las garantías sensatas.Una forma de resolver esto sería reemplazar la lambda con una clase de functor escrita a mano. También es lo que la lambda esencialmente está debajo del capó.
Luego puede obtener la dirección
this
, incluso sin asignar el functor a una variable:Esto tiene la ventaja de que es 100% portátil y extremadamente fácil de razonar y entender.
fuente
struct { void operator()() { std::cout << "Address of this functor is => " << this << '\n'; } } f;
Captura la lambda:
fuente
std::function
embargo, aquí no se necesita la flexibilidad de a , y tiene un costo considerable. Además, copiar / mover ese objeto lo romperá.Es posible, pero depende en gran medida de la plataforma y la optimización del compilador.
En la mayoría de las arquitecturas que conozco, hay un registro llamado puntero de instrucciones. El objetivo de esta solución es extraerlo cuando estamos dentro de la función.
En amd64 El siguiente código debería proporcionarle direcciones cercanas a la función uno.
Pero, por ejemplo, en gcc https://godbolt.org/z/dQXmHm con la
-O3
función de nivel de optimización podría estar en línea.fuente
thread_local
duración automática o de almacenamiento. Lo que intenta obtener aquí es la dirección de retorno de la función, no un objeto. Pero incluso eso no funcionará porque el prólogo de la función generada por el compilador empuja a la pila y ajusta el puntero de la pila para hacer espacio para las variables locales.