Обратные вызовы в C++ | страница 64
Рис. 22. Рекурсивное развертывание пакета параметров для трех аргументов
Использование распределения вызовов для статического набора получателей приведено в Листинг 64.
>void ExternalHandler() // (1)
>{
>}
>struct FO
>{
> void callbackHandler() {}
> void operator() () {}
>};
>int main()
>{
> FO fo; // (2)
> auto lambda = []() {}; // (3)
> auto cb2cl = std::bind(&FO::callbackHandler, fo); // (4)
> Distribute(ExternalHandler, fo, cb2cl, lambda); // (5)
>}
В строках 1, 2, 3, 4 объявлены соответствующие объекты вызова: внешняя функция, функциональный объект, лямбда-выражение, объект для вызова метода класса. Для вызова метода класса в строке 4 объявляется объект связывания (см. п. 4.6.6), в строке 5 происходит распределение вызовов.
5.2.2. Передача данных
Если в вызов необходимо передавать данные, то для этого в описанные выше функции необходимо ввести дополнительный параметр (Листинг 65).
>template
>void Call(CallData& data)
>{
>}
>template
>void Call(CallData data, First& first, Others&…rest)
>{
> first(data); // (3)
> Call(data, rest…); // (4)
>}
>template
>void Distribute(CallData data, CallObjects… objects)
>{
> Call(data, objects…); // (6)
>}
Приведенная реализация повторяет Листинг 63 п. 5.2.1, только теперь в функциях к объектам вызова добавляется параметр data для передачи данных.
Пример распределения для статического набора получателей с передачей данных представлен в Листинг 66.
>void ExternalHandler(int eventID) // (1)
>{
>}
>struct FO
>{
> void callbackHandler(int eventID) {}
> void operator() (int eventID) {}
>};
>int main()
>{
> using namespace std::placeholders;
> FO fo; // (2)
> auto lambda = [](int eventID) {}; // (3)
> auto cb2cl = std::bind(&FO::callbackHandler, fo, _1); // (4)
> int eventID = 0; // (5)
> Distribute(eventID, ExternalHandler, fo, cb2cl, lambda); // (6)
>}
В строках 1, 2, 3, 4 объявлены соответствующие объекты вызова: внешняя функция, функциональный объект, лямбда-выражение, объект для вызова метода класса. Для вызова метода класса в строке 4 объявляется объект связывания (см. п. 4.6.6), в строке 5 объявляется переменная для передачи данных. В строке 6 происходит распределение вызовов, первым параметром передается аргумент данных