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



>struct TupleIterator

>{

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

>  {

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

>    std::get(callObjects)(callData…);                         // (4)

>    TupleIterator::IterateTupleItem(callObjects, callData…);  // (5)

>  }

>};


>template  // (6)

>struct TupleIterator<0, CallObjects, CallData…>     // (7)

>{

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

>  {

>  }

>};


>template                         // (9)

>void Distribute2(std::tuple callObjects, CallData… callData)  // (10)

>{

>  TupleIterator  // (11)

>  <

>  sizeof…(CallObjects),      // (12)

>  std::tuple,  // (13)

>  CallData…                  // (14)

>>

>::IterateTupleItem(callObjects, callData…);  // (15)

>}


В строке 1 объявляется шаблон структуры. Параметрами шаблона выступают индекс элемента кортежа, сам кортеж и пакет параметров, который определяет данные, передаваемые в вызываемый объект.

Внутри структуры в строке 2 объявлена функция, осуществляющая выполнение вызова для элемента кортежа. Входными параметрами этой функции будет кортеж объектов вызова и пакет данных вызова, элемент кортежа определяется индексом – параметром шаблона. Функция объявлена статической, чтобы не объявлять экземпляр структуры в процессе вызова. По сути дела, структура здесь не несет функциональной нагрузки, она выступает в качестве оболочки, чтобы обеспечить специализацию функции по индексу (поскольку непосредственная специализация шаблонов функций невозможна).

В строке 3 осуществляется пересчет индекса: от размера (количества элементов) кортежа отнимается текущий индекс. Это необходимо для того, чтобы обход кортежа осуществлялся в прямом порядке, от первого элемента к последнему. Если не выполнять пересчет индексов, то обход будет происходить в обратном порядке.

В строке 4 осуществляется вызов объекта. С помощью вызова get по пересчитанному индексу осуществляется доступ к соответствующему элементу кортежа. Для указанного элемента выполняется вызов, на вход ему передается пакет данных callData, распакованный в список аргументов.

В строке 5 происходит рекурсивный вызов. Объявляется структура с новым значением параметра-индекса, уменьшенным на единицу. Вызывается соответствующая функция с передачей кортежа объектов и пакета параметров, и процесс повторяется заново.