以指定的顺序迭代元组的元素

时间:2016-01-22 20:30:51

标签: c++ tuples metaprogramming operator-precedence

可以迭代元组的元素并应用这种实现的函数:

#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 个答案:

答案 0 :(得分:3)

在C ++ 1z中,将其折叠在逗号运算符上:

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

在此之前,请将其解压缩到 braced-init-list 中,例如:

auto l = {0, (void(f(get<Indices>(t))), 0)... };
(void) l;