boost::function
позволяет operator()
связать что-либо с правильной подписью в качестве параметра, а результат вашей привязки может быть вызван с параметром int
, поэтому он может быть привязан к function<void(int)>
.
Вот как это работает (это описание одинаково применимо std::function
):
boost::bind(&klass::member, instance, 0, _1)
возвращает такой объект
struct unspecified_type
{
... some members ...
return_type operator()(int i) const { return instance->*&klass::member(0, i);
}
где return_type
и int
выводятся из сигнатуры klass::member
, а указатель функции и связанный параметр фактически хранятся в объекте, но это не важно
Теперь boost::function
не выполняет никакой проверки типов: он принимает любой объект и любую подпись, которую вы указываете в параметре шаблона, и создает объект, который может быть вызван в соответствии с вашей подписью, и вызывает этот объект. Если это невозможно, это ошибка компиляции.
boost::function
на самом деле такой объект:
template <class Sig>
class function
{
function_impl<Sig>* f;
public:
return_type operator()(argument_type arg0) const { return (*f)(arg0); }
};
где return_type
и argument_type
извлекаются из Sig
, и f
динамически размещается в куче. Это необходимо, чтобы разрешить привязку к совершенно несвязанным объектам разного размера boost::function
.
function_impl
это просто абстрактный класс
template <class Sig>
class function_impl
{
public:
virtual return_type operator()(argument_type arg0) const=0;
};
Класс, который выполняет всю работу, является конкретным производным классом boost::function
. Есть по одному для каждого типа объекта, которому вы назначаетеboost::function
template <class Sig, class Object>
class function_impl_concrete : public function_impl<Sig>
{
Object o
public:
virtual return_type operator()(argument_type arg0) const=0 { return o(arg0); }
};
Это означает, что в вашем случае назначение функции boost:
- создает экземпляр типа
function_impl_concrete<void(int), unspecified_type>
(конечно, это время компиляции)
- создает новый объект этого типа в куче
- назначает этот объект члену f функции boost ::
Когда вы вызываете объект функции, он вызывает виртуальную функцию своего объекта реализации, которая направляет вызов вашей исходной функции.
ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: обратите внимание, что имена в этом объяснении намеренно придуманы. Любое сходство с реальными людьми или персонажами ... вы это знаете. Целью было проиллюстрировать принципы.