Sans passer trop de temps à passer en revue le code source du boost, quelqu'un pourrait-il me donner un rapide aperçu de la façon dont boost bind est implémenté?Comment le boost fonctionne-t-il dans les coulisses en général?
Répondre
J'aime ce morceau de la source bind
:
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
};
dit que vous presque tout ce que vous devez savoir, vraiment.
L'en-tête bind_template
se développe en une liste de définitions en ligne operator()
. Par exemple, le plus simple:
result_type operator()()
{
list0 a;
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
}
On peut voir les BOOST_BIND_RETURN
macro à return
se dilate à ce point si la ligne est plus comme return l_(type...)
.
La seule version du paramètre est ici:
template<class A1> result_type operator()(A1 & a1)
{
list1<A1 &> a(a1);
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
}
Il est assez similaire.
Les classes listN
sont des wrappers pour les listes de paramètres. Il y a beaucoup de magie profonde ici que je ne comprends pas trop. Ils ont également surchargé operator()
qui appelle la mystérieuse fonction unwrap
. Ignorer quelques surcharges spécifiques du compilateur, il ne fait pas beaucoup:
// 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 convention de nommage semble être: F
est le type du paramètre de fonction bind
. R
est le type de retour. L
a tendance à être une liste de types de paramètres. Il y a aussi beaucoup de complications car il n'y a pas moins de neuf surcharges pour différents nombres de paramètres. Il vaut mieux ne pas trop insister là-dessus.
Je pense que c'est une classe modèle qui déclare une variable membre pour les arguments que vous voulez lier et surcharge() pour le reste des arguments.
Par ailleurs, si bind_t
est réduite et simplifiée en incluant boost/bind/bind_template.hpp
, il devient plus facile de comprendre comme ce qui suit:
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_;
};
cela ne semble pas simple pour moi ... pourquoi le '# define BOOST_BIND_RETURN return' nécessaire? pourquoi ne pas simplement revenir? – Ha11owed
Je ne comprends toujours pas. Qu'est-ce qui appelle le constructeur à 'bind_t'? – ThomasMcLeod
@ Ha11owed parce que de cette façon, ils peuvent utiliser l'en-tête pour les modèles qui n'ont pas de valeur de retour! –