Обратные вызовы в C++ | страница 78
>template
>class DynamicDistributor
>{
> /**********************……**********************************/
> template
> void operator()(CallbackReturn callbackReturn, ArgumentList… arguments)
> {
> for (auto& callObject : callObjects)
> {
> callbackReturn(callObject(arguments…)); // (2)
> }
> }
>private:
> std::list< std::function
>};
Реализация совпадает с Листинг 82 п. 5.6.1, только добавляется еще один перегруженный оператор. Его шаблон объявлен строке 1, параметром шаблона является тип аргумента, через который будет выполняться обратный вызов. В строке 2 происходит вызов объекта, результат возвращается через аргумент, переданный как входной параметр функции.
Пример распределения вызовов для динамического набора получателей приведен в Листинг 83.
>struct FO
>{
> int operator() (int eventID) { return 10; }
> int callbackHandler(int eventID) { return 100; }
>};
>int ExternalHandler(int eventID)
>{
> return 0;
>}
>int main()
>{
> int eventID = 0;
> FO fo;
> auto lambda = [](int eventID) { return 0; };
> auto binding = std::bind(&FO::callbackHandler, fo, std::placeholders::_1);
> DynamicDistributor
> distributor.addCallObject(fo); // (2)
> distributor.addCallObject(ExternalHandler); // (3)
> distributor.addCallObject(binding); // (4)
> distributor.addCallObject(lambda); // (5)
> distributor(eventID); // (6)
> auto onReturnValue = [](int callResult) {}; // (7)
> distributor(onReturnValue, eventID); // (8)
>}
В строке 1 инстанциирован класс распределителя с заданной сигнатурой функции. В строке 2, 3, 4, 5 в распределитель добавляются объекты вызова различного типа. В строке 6 запускается распределение вызовов, в результате которого будут вызваны добавленные объекты. В строке 7 объявлено лямбда-выражение для получения результатов, при вызове соответствующего оператора 8 это выражение будет вызвано для каждого возвращаемого значения.
Касательно модификации содержимого контейнера наш распределитель поддерживает только одну операцию – добавление получателя. Ни удаление, ни модификация получателей не поддерживается. Это связано с тем, что получатели не идентифицированы, и поэтому невозможно узнать, в каком элементе контейнера хранится соответствующий объект вызова