Обратные вызовы в C++ | страница 73



Листинг 75. Распределитель для статического набора получателей

>template  // (1)

>class StaticDistributorVoid

>{

>public:

>  StaticDistributorVoid (CallObjects… objects) : callObjects(objects…) {}  // (2)

>  auto& tuple() {  return callObjects; }  // (3)


>  template          // (4)

>  void operator() (CallData… callData)

>  {

>    Distribute2(callObjects, callData…);

>  }

>private:

>  std::tuple callObjects;  // (5)

>};


В строке 1 объявлен шаблон класса, параметром которого выступает пакет объектов вызова. Кортеж для хранения объектов объявлен в строке 5, он инициализируется в конструкторе 2. Для доступа к кортежу реализован метод 3, который позволяет, если необходимо, изменить его содержимое.

В строке 4 объявлен перегруженный оператор, который осуществляет распределение. Этот оператор вызывает распределяющую функцию (реализацию см. Листинг 69 п. 5.3.3), которую при желании можно сделать членом класса.


Пример использования распределителя приведен в Листинг 76.

Листинг 76. Использование распределителя для статического набора

>struct FO

>{

>  void operator() (int eventID) {}

>  void callbackHandler(int eventID) {}

>};


>void ExternalHandler(int eventID) {}


>int main()

>{

>  FO fo;

>  int eventID = 0;

>  auto lambda = [](int eventID) {};

>  auto callbackToMethod = std::bind(&FO::callbackHandler, fo, std::placeholders::_1);


>  StaticDistributorVoid distributor(ExternalHandler, fo, callbackToMethod, lambda);  // (1)


>  distributor(eventID);  // (2)

>}


Как видим, использование очень простое: в строке 1 объявляется распределитель, в конструктор передаются объекты вызова, через перегруженный оператор 2 производятся вызовы сохраненных объектов.

5.5.2. Распределение с возвратом результатов

Если нужно получить значения, возвращаемые вызовами, то в распределителе необходимо модифицировать перегруженный оператор (Листинг 77).

Листинг 77. Распределитель для статического набора с возвратом результатов

>template  // (1)

>class StaticDistributorReturn

>{

>public:

>  StaticDistributorReturn(CallObjects… objects) : callObjects(objects…) {}  // (2)

>  auto& tuple() { return callObjects; }  // (3)


>  template         // (4)

>  auto operator() (CallData… callData)

>  {

>      return DistributeReturn(callObjects, callData…);

>  }

>private:

>  std::tuple callObjects;  // (5)

>};


В строке 4 объявлен перегруженный оператор с возвращаемым типом auto. Указанный тип будет выведен из значения, возвращаемого соответствующей распределяющей функцией. (реализацию см. в Листинг 73 п. 5.4.1).