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 ::
Коли ви викликаєте об'єкт функції, він викликає віртуальну функцію об'єкта його реалізації, яка направить виклик до вашої вихідної функції.
ЗАМОВЛЕННЯ: Зверніть увагу, що імена в цьому поясненні свідомо вигадані. Будь-яка схожість із реальними особами чи персонажами ... ви це знаєте. Метою було проілюструвати принципи.