Reputation: 11406
It's possible to iterate over a tuple's elements and apply a function with this sort of implementation:
#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);
}
Because this implementation relies on the order of parameters passed to the swallow()
function, the order of f
's invocations are unspecified.
One way to force the invocations of f
to agree with the order of tuple elements would be to use recursion:
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);
}
The problem with this recursive solution is that it may introduce disappointing compile-time performance.
Is there a more efficient solution that would produce the desired evaluation order?
I know that many fine c++ libraries for metaprogramming and tuple manipulation are available, but I am interested in the implementation details of a solution, should one exist.
Upvotes: 2
Views: 484
Reputation: 137315
In C++1z, fold it over the comma operator:
(... , void(f(get<Indices>(t))));
Before that, unpack into a braced-init-list, e.g.:
auto l = {0, (void(f(get<Indices>(t))), 0)... };
(void) l;
Upvotes: 3