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