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>
(это время компиляции, конечно)
- создает новый объект этого типа в куче
- присваивает этот объект дзета члена повышения :: функция
Когда вы вызываете объект функции, он вызывает виртуальную функцию объекта реализации, которая будет направлять вызов вашей исходной функции.
ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Обратите внимание, что имена в этом объяснении намеренно составлены. Любое сходство с реальными людьми или персонажами ... вы это знаете. Целью было проиллюстрировать принципы.
Dupe: http://stackoverflow.com/questions/112738/how-does-boost-bind-work-behind-the-scenes-in-general –
не очень - этот вопрос связан с привязкой и функцией –
Да и таким образом, все еще остается вопрос о том, как связать map void MyClass: DoSomething (std :: string str, int number) для boost :: function через bind (& MyClass :: DoSomething, instance, «Hello World», _1) –