cómo boost :: function y boost :: bind work

No me gusta tener cajas mágicas dispersas por todo mi código … ¿Cómo funcionan exactamente estas dos clases para permitir básicamente que cualquier función se asigne a un objeto de función, incluso si la función tiene un conjunto de parámetros completamente diferente al que estoy pasando por boost::bind

Incluso funciona con diferentes convenciones de llamada (es decir, los métodos de miembro son __thiscall esta __thiscall bajo VC, pero las funciones “normales” son generalmente __cdecl o __stdcall para aquellos que necesitan ser compatibles con C.

    boost::function permite que cualquier cosa con un operator() con la firma correcta se vincule como parámetro, y el resultado de su enlace se puede invocar con un parámetro int , por lo que puede vincularse a la function .

    Así es como funciona (esta descripción se aplica tanto para std::function ):

    boost::bind(&klass::member, instance, 0, _1) devuelve un objeto como este

     struct unspecified_type { ... some members ... return_type operator()(int i) const { return instance->*&klass::member(0, i); } 

    donde return_type e int se deducen de la firma de klass::member , y el puntero de función y el parámetro enlazado se almacenan de hecho en el objeto, pero eso no es importante

    Ahora, boost::function no hace ninguna verificación de tipo: tomará cualquier objeto y cualquier firma que proporciones en su parámetro de plantilla, y creará un objeto que se puede llamar de acuerdo con tu firma y llama al objeto. Si eso es imposible, es un error de comstackción.

    boost::function es en realidad un objeto como este:

     template  class function { function_impl* f; public: return_type operator()(argument_type arg0) const { return (*f)(arg0); } }; 

    donde return_type y argument_type se extraen de Sig , y f se asigna dinámicamente en el montón. Eso es necesario para permitir que objetos completamente no relacionados con diferentes tamaños se unan a boost::function .

    function_impl es solo una clase abstracta

     template  class function_impl { public: virtual return_type operator()(argument_type arg0) const=0; }; 

    La clase que hace todo el trabajo, es una clase concreta derivada de boost::function . Hay uno para cada tipo de objeto que asigna a boost::function

     template  class function_impl_concrete : public function_impl { Object o public: virtual return_type operator()(argument_type arg0) const=0 { return o(arg0); } }; 

    Eso significa que en su caso, la asignación para boost la función:

    1. instancia un tipo function_impl_concrete (eso es tiempo de comstackción, por supuesto)
    2. crea un nuevo objeto de ese tipo en el montón
    3. asigna este objeto al miembro f de la función boost ::

    Cuando llama al objeto de función, llama a la función virtual de su objeto de implementación, que dirigirá la llamada a su función original.

    DESCARGO DE RESPONSABILIDAD: Tenga en cuenta que los nombres en esta explicación se componen deliberadamente. Cualquier parecido con personas o personajes reales … lo sabes. El propósito fue ilustrar los principios.