Перебор элементов кортежа в указанном последовательном порядке

Можно перебрать элементы кортежа и применить функцию с такой реализацией:

#include <tuple>
#include <utility>

template<class... Args>
void swallow(Args&&...)
{
}

template<size_t... Indices, class Function, class Tuple>
void tuple_for_each_in_unspecified_order_impl(std::index_sequence<Indices...>, Function f, const Tuple& t)
{
  swallow(f(std::get<Indices>(t))...);
}

template<class Function, class... Types>
void tuple_for_each_in_unspecified_order(Function f, const std::tuple<Types...>& t)
{
  tuple_for_each_in_unspecified_order_impl(std::index_sequence_for<Types...>(), f, t);
}

Поскольку эта реализация зависит от порядка параметров, передаваемых swallow() функция, порядок fПризывы не уточняются.

Один из способов заставить призывы f согласиться с порядком элементов кортежа будет использовать рекурсию:

template<class Function, class Tuple>
void tuple_for_each_in_order_impl(std::index_sequence<>, Function f, const Tuple& t) {}

template<size_t I, size_t... Indices, class Function, class Tuple>
void tuple_for_each_in_order_impl(std::index_sequence<I,Indices...>, Function f, const Tuple& t)
{
  f(std::get<I>(t));

  tuple_for_each_in_order_impl(std::index_sequence<Indices...>(), f, t);
}

template<class Function, class... Types>
void tuple_for_each_in_order(Function f, const std::tuple<Types...>& t)
{
  tuple_for_each_in_order_impl(std::index_sequence_for<Types...>, f, t);
}

Проблема этого рекурсивного решения заключается в том, что оно может привести к разочаровывающей производительности во время компиляции.

Есть ли более эффективное решение, которое дало бы желаемый порядок оценки?

Я знаю, что доступно много прекрасных библиотек C++ для метапрограммирования и манипулирования кортежами, но меня интересуют детали реализации решения, если таковое существует.

1 ответ

В C++1z сложите его через оператор запятой:

(... , void(f(get<Indices>(t))));

Перед этим распакуйте в список braced-init-list, например:

auto l = {0, (void(f(get<Indices>(t))), 0)... };
(void) l;
Другие вопросы по тегам