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); }
};
Это означает, что в вашем случае назначение для функции повышения:
- создает экземпляр типа
function_impl_concrete<void(int), unspecified_type>
(это, конечно, время компиляции)
- создает новый объект этого типа в куче
- назначает этот объект f члену boost :: function
Когда вы вызываете объект функции, он вызывает виртуальную функцию своего объекта реализации, которая направит вызов вашей исходной функции.
ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: обратите внимание, что имена в этом объяснении специально составлены. Любое сходство с реальными людьми или персонажами ... вы это знаете. Цель состояла в том, чтобы проиллюстрировать принципы.