c++ boost boost-bind boost-function

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



boost-bind boost-function (1)

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<void(int)> .

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 compilación.

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

template <class Sig> class function { function_impl<Sig>* 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 Sig> 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 Sig, class Object> class function_impl_concrete : public function_impl<Sig> { 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 aumentar la función:

  1. instancia un tipo function_impl_concrete<void(int), unspecified_type> (eso es tiempo de compilació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.

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.