Как Boost Bind работает за кулисами в целом?
Не тратя много времени на просмотр исходного кода boost, не мог бы кто-нибудь дать мне краткое изложение того, как реализовано boost bind?
3 ответа
Мне нравится этот кусок 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
макрос расширяется до return
на данный момент, так что линия больше похожа return l_(type...)
,
Версия с одним параметром находится здесь:
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
тип параметра функции для bind
, R
это тип возвращаемого значения. L
как правило, список типов параметров. Есть также много сложностей, потому что существует не менее девяти перегрузок для различного числа параметров. Лучше не останавливаться на этом слишком много.
Кстати, если 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_;
};
Я думаю, что это шаблонный класс, который объявляет переменную-член для аргументов, которые вы хотите связать, и перегрузку () для остальных аргументов.