Domanda

Senza spendere molto tempo a rivedere il codice sorgente boost, qualcuno potrebbe darmi una rapida panoramica di come viene implementato il boost bind?

È stato utile?

Soluzione

Mi piace questo pezzo del sorgente 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

};

Ti dice quasi tutto quello che devi sapere, davvero.

L'intestazione bind_template si espande in un elenco di definizioni inline operator () . Ad esempio, il più semplice:

result_type operator()()
{
    list0 a;
    BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
}

Possiamo vedere la macro BOOST_BIND_RETURN si espande in return a questo punto quindi la linea è più simile a return l_ (type ...) .

La versione con un parametro è qui:

template<class A1> result_type operator()(A1 & a1)
{
    list1<A1 &> a(a1);
    BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
}

È abbastanza simile.

Le classi listN sono wrapper per gli elenchi di parametri. C'è molta magia profonda in corso qui che non capisco davvero troppo. Hanno anche sovraccaricato l'operatore () che chiama la misteriosa funzione unwrap . Ignorando alcuni sovraccarichi specifici del compilatore, non fa molto:

// 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 convenzione di denominazione sembra essere: F è il tipo del parametro della funzione da associare . R è il tipo restituito. L tende ad essere un elenco di tipi di parametri. Ci sono anche molte complicazioni perché non ci sono meno di nove sovraccarichi per diversi numeri di parametri. Meglio non soffermarsi troppo su questo.

Altri suggerimenti

A proposito, se bind_t è compresso e semplificato includendo boost / bind / bind_template.hpp , diventa più facile capire come il seguente:

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

};

Penso che sia una classe modello che dichiara una variabile membro per gli argomenti che si desidera associare e overload () per il resto degli argomenti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top