¿Cómo funciona Boost Bind entre bastidores en general?
-
02-07-2019 - |
Pregunta
Sin pasar mucho tiempo revisando el código fuente de impulso, ¿alguien podría darme un resumen rápido de cómo se implementa el enlace de impulso?
Solución
Me gusta esta pieza del bind
fuente:
template<class R, class F, class L> class bind_t
{
public:
typedef bind_t this_type;
bind_t(F f, L const & l): f_(f), l_(l) {}
#define BOOST_BIND_RETURN return
#include <boost/bind/bind_template.hpp>
#undef BOOST_BIND_RETURN
};
Te dice casi todo lo que necesitas saber, de verdad.
El bind_template
el encabezado se expande a una lista de en línea operator()
definiciones.Por ejemplo, el más sencillo:
result_type operator()()
{
list0 a;
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
}
Podemos ver el BOOST_BIND_RETURN
macro se expande a return
en este punto la línea es más parecida return l_(type...)
.
La versión de un parámetro está aquí:
template<class A1> result_type operator()(A1 & a1)
{
list1<A1 &> a(a1);
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
}
Es bastante parecido.
El listN
Las clases son contenedores para las listas de parámetros.Hay mucha magia profunda aquí que realmente no entiendo demasiado.También se han sobrecargado operator()
que llama lo misterioso unwrap
función.Ignorando algunas sobrecargas específicas del compilador, no hace mucho:
// unwrap
template<class F> inline F & unwrap(F * f, long)
{
return *f;
}
template<class F> inline F & unwrap(reference_wrapper<F> * f, int)
{
return f->get();
}
template<class F> inline F & unwrap(reference_wrapper<F> const * f, int)
{
return f->get();
}
La convención de nomenclatura parece ser: F
es el tipo de parámetro de función a bind
. R
es el tipo de devolución. L
tiende a ser una lista de tipos de parámetros.También hay muchas complicaciones porque hay no menos de nueve sobrecargas para diferentes números de parámetros.Lo mejor es no insistir demasiado en eso.
Otros consejos
Por cierto, si bind_t
se contrae y se simplifica al incluir boost/bind/bind_template.hpp
, se vuelve más fácil de entender de la siguiente manera:
template<class R, class F, class L>
class bind_t
{
public:
typedef bind_t this_type;
bind_t(F f, L const & l): f_(f), l_(l) {}
typedef typename result_traits<R, F>::type result_type;
...
template<class A1>
result_type operator()(A1 & a1)
{
list1<A1 &> a(a1);
return l_(type<result_type>(), f_, a, 0);
}
private:
F f_;
L l_;
};
Creo que es una clase de plantilla que declara una variable miembro para los argumentos que desea vincular y sobrecarga () para el resto de los argumentos.