33

ブーストソースコードのレビューに長い時間を費やすことなく、誰かがブーストバインドがどのように実装されているかを簡単に説明してもらえますか?

4

3 に答える 3

25

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

};

本当に、あなたが知る必要があるほとんどすべてを教えてくれます。

bind_templateヘッダーは、インラインoperator()定義のリストに展開されます。たとえば、最も単純なものは次のとおりです。

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

この時点でBOOST_BIND_RETURNマクロが に展開されていることがわかるため、行はより.returnreturn l_(type...)

1 つのパラメーターのバージョンは次のとおりです。

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

かなり似ています。

listNクラスは、パラメーター リストのラッパーです。ここには、私があまり理解していない深い魔法がたくさんあります。彼らはまたoperator()、謎のunwrap関数を呼び出すオーバーロードを行いました。いくつかのコンパイラ固有のオーバーロードを無視すると、多くのことはできません:

// 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();
}

命名規則は次のようです: へFの関数パラメータの型ですbindRリターンタイプです。Lパラメータタイプのリストになる傾向があります。さまざまな数のパラメーターに対して 9 つ以上のオーバーロードがあるため、多くの複雑さも生じます。そこはあまり考えないほうがいいです。

于 2008-09-22T04:10:20.280 に答える
2

ちなみに、bind_tを含めて折りたたんで簡略化するboost/bind/bind_template.hppと、次のようにわかりやすくなります。

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

};
于 2009-12-03T13:10:25.687 に答える
0

バインドしたい引数にメンバー変数を宣言し、残りの引数に()をオーバーロードするテンプレートクラスだと思います。

于 2008-09-22T01:19:41.533 に答える