Перебор элементов кортежа в указанном последовательном порядке
Можно перебрать элементы кортежа и применить функцию с такой реализацией:
#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;