es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Existe una “referencia” útil que se pueda adquirir desde una std::function de vuelta a la función/lambada almacenada?

En C, si uno quiere conocer/adquirir una referencia útil de vuelta a un callback/otra función, puede hacerlo fácilmente casteando la función a un void*. Más tarde, por ejemplo durante la depuración, se puede examinar el puntero y rastrearlo hasta la función original (por ejemplo, a través de la salida del mapa del compilador o incluso del depurador del editor).

Este tipo de información es muy útil al utilizar “migas de pan” – por ejemplo, un búfer circular de void*s – para depurar el flujo de una aplicación.

En C++, con std::function, es posible obtener un puntero sin procesar a través de la función miembro target(), sin embargo, esto solo funciona si se conoce de antemano el tipo preciso del destino almacenado (es decir, una función C estándar); sin embargo, cuando se almacenan funciones anónimas, esto deja de ser el caso, ya que el destino ya no es una simple void() para una std::function y, por lo tanto, devolverá nullptr.

En vista de lo anterior, ¿cuál es la siguiente mejor referencia a la que se puede acceder al destino almacenado de tal manera que se pueda usar, preferiblemente, después de que la ejecución de la aplicación haya finalizado o mientras se encuentra pausada con el depurador adjunto?

¿Se puede adquirir el destino a través de alguna magia de plantilla, conservando aún la semántica/usabilidad de std::function dentro del código de la biblioteca? Esto debería incluir la captura de funciones anónimas y funciones C puras.

Algunas notas:
– No estoy preguntando cómo hacer depuración
– No estoy preguntando cómo se podría capturar información de depuración desde el destino almacenado; imagina que esto es una biblioteca en lugar de código de cliente.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Si el tipo exacto del objetivo almacenado en una std::function no se conoce de antemano, y la función miembro target<func_type>() devuelve nullptr, la siguiente mejor referencia al objetivo almacenado sería utilizar una función o functor envoltorio que llame a la función almacenada y almacene la información necesaria. Esta función o functor envoltorio se puede llamar en lugar de la std::function original y puede almacenar información como el nombre o la dirección de la función en memoria, para su uso en la depuración más adelante.

    En cuanto a la adquisición del objetivo mediante técnicas de magia de plantillas, una posible solución es utilizar técnicas de borrado de tipos como std::any o boost::any para almacenar el objetivo en un contenedor de tipo borrado. Esto permitiría capturar lambdas y funciones puras de C dentro del mismo contenedor, mientras se retienen la semántica y la usabilidad de std::function dentro del código de la biblioteca. Sin embargo, este enfoque vendría con cierta sobrecarga de rendimiento debido a la necesidad de comprobaciones y conversiones de tipo dinámico.

Comments are closed.