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



С каждой итерацией значение индекса уменьшается, и когда оно станет равным нулю, необходимо остановить итерации, поскольку все элементы кортежа будут посещены. Для этой цели в строке 6 объявлена специализация структуры для нулевого индекса. Тело функции в этой структуре пустое, таким образом, рекурсия будет завершена.

В строке 9 объявлен шаблон распределяющей функции. Этот шаблон имеет два пакета параметров: пакет объектов вызова и пакет данных вызова, типы содержимого пакетов будут выводиться из входных аргументов. В строке 10 объявляется сама функция, которая на вход принимает два аргумента: кортеж объектов вызова и пакет данных вызова.

В строке 11 запускается процесс итерации путем инстанциирования шаблона TupleIterator. Аргументами шаблона выступают: количество объектов вызова (строка 12), вычисляется с помощью операции sizeof применительно к соответствующему пакету параметров; кортеж объектов вызова (строка 13); данные, передаваемые в вызов (строка 14). В строке 15 вызывается стартовая функция итерации с передачей соответствующих аргументов. Как видим, начальное значение индекса равно количеству объектов вызова, которое затем с каждой новой итерацией будет уменьшаться на единицу, в то время как пересчитываемый индекс, соответственно, увеличивается.

5.3.4. Способ 3: объекты и данные в кортежах

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

Листинг 70. Распределение при упаковке объектов и данных в кортежи

>template          // (1)

>struct TupleIterator3

>{

>  static void IterateTupleItem(CallObjects& callObjects, CallData& callData)  // (2)

>  {

>      const std::size_t idx = std::tuple_size_v – Index;         // (3)

>      std::apply(std::get(callObjects), callData);                       // (4)

>      TupleIterator3::IterateTupleItem(callObjects, callData);  // (5)

>  }

>};


>template  // (6)

>struct TupleIterator3<0, CallObjects, CallData>    // (7)

>{

>  static void IterateTupleItem(CallObjects& callObjects, CallData& callData)  // (8)

>  {

>  }

>};


>template                                     // (9)

>void Distribute3(std::tuple callObjects, std::tuple callData)  // (10)