Содержание

Зачем это нужно

Во многих современных языках существует понятие «делегата» - некоторой сущности, позволяющей косвенно вызвать тот или иной метод. Наиболее близкая аналогия в С++ - это указатель на функцию или член класса. Но каждый разработчик на С++, кто сталкивался с такого рода указателями, в итоге выясняет, что они - не полноценный аналог делегата. По двум причинам: 1. Указатель на функцию и указатель на член класса не могут быть преобразованы друг в друга. 2. Для доступа к члену класса по указателю обязательно требуется указатель на объект, относительно которого производится вызов. А по этому, если указатели на свободные функции или статические функции еще можно как-то рассматривать в качестве делегатов, то с указателями на члены класса все гозаздо сложнее. Для устранения этих проблем и был создан шаблонный класс boost::function (а точнее - набор шаблонных классов).

Что это такое? По сути - boost::function (точнее, результат его инстанцирования) - это функтор (функциональный объект), к которому применим оператор «()» (вызова функции). А потому в исходный тексте программы вызов метода напрямую или через boost::function ничем не отличимы.

В качестве аргументов шаблона boost::function принимает сигнатуру метода, который он будет «эмулировать». Например:

boost::function<void ()> foo1;
// (соответствует методу с сигнатурой void foo1();)
 
boost::function<int (int, float, SomeClass&)> foo2;
// соответствует методу 
// int foo2(int arg1, float arg2, SomeClass& arg3)
 
// и т. д.

А инициализироваться может либо указателем на соответствующий метод, либо другим функциональным объектом, который может быть вызван с указанными параметрами:

void foo1(int a) {;}
 
struct Foo1
{
   void operator() (int a) {;}
}
 
boost::function<void (int)> Delegate;
 
//...
Delegate = foo1;
// ...
Delegate(10); // будет реально вызван foo1(10)
// ...
// ...
Delegate = Foo1();
// ...
Delegate(10); // будет вызван Foo1::operator()(10);

Как это использовать

Недостатки

Достоинства