boost::function
permite cualquier cosa con operator()
con la firma correcta para vincularse como parámetro, y el resultado de su enlace se puede invocar con un parámetro int
, por lo que puede vincularse al function<void(int)>
.
Esto es cómo funciona (esta descripción se aplica por igual a std::function
):
boost::bind(&klass::member, instance, 0, _1)
devuelve un objeto como éste
struct unspecified_type
{
... some members ...
return_type operator()(int i) const { return instance->*&klass::member(0, i);
}
donde el return_type
y int
se infiere a partir de la firma del klass::member
, y el El puntero a la función y el parámetro enlazado están de hecho almacenados en el objeto, pero eso no es importante
Ahora, boost::function
hace no hacer ninguna verificación de tipo: tomará cualquier objeto y cualquier firma que proporcione en su parámetro de plantilla, y creará un objeto que se pueda llamar de acuerdo con su firma y llame 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 el 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 sólo 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 se 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, en su caso, la cesión a estimular la función:
- instancia un tipo
function_impl_concrete<void(int), unspecified_type>
(que es el tiempo de compilación, por supuesto)
- crea un nuevo objeto de ese tipo en el montón
- asigna este objeto para el miembro f de la función impulso ::
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.
Dupe: http://stackoverflow.com/questions/112738/how-does-boost-bind-work-behind-the-scenes-in-general –
no realmente - esta pregunta es sobre enlace y función –
Sí y por lo tanto, aún queda la cuestión de cómo enlazar map void MyClass: DoSomething (std :: string str, int number) para impulsar :: function mediante bind (& MyClass :: DoSomething, instancia, "Hello World", _1) –