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