2008-09-22 2 views

Répondre

24

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.

+2

cela ne semble pas simple pour moi ... pourquoi le '# define BOOST_BIND_RETURN return' nécessaire? pourquoi ne pas simplement revenir? – Ha11owed

+0

Je ne comprends toujours pas. Qu'est-ce qui appelle le constructeur à 'bind_t'? – ThomasMcLeod

+2

@ 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! –

0

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.

2

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_; 

}; 
Questions connexes