Обратные вызовы в C++ | страница 72
Рис. 23. Формирование кортежа возвращаемых значений
5.4.2. Анализ результатов
Итак, мы получили возвращаемые значения в виде кортежа. Как нам проанализировать полученные результаты? Существуют следующие способы анализа содержимого кортежа:
• доступ к элементам кортежа по индексу с помощью std::get;
• обход кортежа;
• использование структурных привязок.
Пример анализа значений, возвращаемых распределением вызовов, приведен в Листинг 74.
>struct FO
>{
> int operator() (int eventID)
> {
> return 10;
> }
>};
>struct SResult
>{
> unsigned int code;
> const char* description;
>};
>SResult ExternalHandler(int eventID)
>{
> return SResult{ 1, "this is an error" };
>}
>int main()
>{
> FO fo;
> int eventID = 0;
> auto lambda = [](int eventID) { return 0.0; };
> auto results = DistributeReturn( std::tuple(fo, ExternalHandler, lambda), eventID); // (1)
> int foRes = std::get<0>(results); // (2)
> SResult ExtRes = std::get<1>(results); // (3)
> double lambdaRes = std::get<2>(results); // (4)
> auto [foRes1, ExtRes1, lambdaRes1] = results; // (5)
> auto [foRes2, ExtRes2, lambdaRes2] = DistributeReturn(std::tuple(fo, ExternalHandler, lambda), eventID); // (6)
>}
После выполнения распределения в строке 1 в переменную results помещен кортеж с результатами выполнения вызова. В строках 2, 3, 4 показано получение результатов с помощью запроса элементов кортежа по индексу, в строке 5 показано использование структурных привязок. В строке 6 показано, как можно использовать структурные привязки без промежуточной переменной results. Обход кортежа здесь не рассматривается, поскольку он был подробно описан в п. 5.3.3.
5.5. Распределитель для статического набора
5.5.1. Распределение без возврата результатов
До сих пор мы выполняли распределение с помощью функции, что вызывает определенные неудобства. Во-первых, вызов распределяющей функции получается громоздким, потому что приходится перечислять все объекты, участвующие в распределении. Во-вторых, требуются дополнительные операции, потому что в зависимости от способа настройки либо объекты вызова, либо аргументы сигнатуры необходимо упаковать в кортеж. Хорошим решением было бы предварительно сохранить нужные объекты, для чего нам понадобится распределитель в виде класса. Реализация приведена в Листинг 75.