在元组上推广for_each以接受可变数量的参数

时间:2011-04-12 19:21:47

标签: c++ c++11 variadic-functions variadic-templates

目前,我有:

template <unsigned I,
          unsigned N,
          typename Tuple,
          typename UnaryFunction>
struct for_;

template <unsigned N, typename Tuple, typename UnaryFunction>
struct for_<N, N, Tuple, UnaryFunction> {
  static
  void call(const Tuple&, UnaryFunction) {}
};

template <unsigned I,
          unsigned N,
          typename Tuple,
          typename UnaryFunction>
struct for_ {
  static
  void call(Tuple&& x, UnaryFunction f) {
    f(get<I>(x));
    for_<I + 1, N, Tuple, UnaryFunction>::call(std::forward<Tuple>(x), f);
  }
};

template <typename Tuple, typename UnaryFunction>
inline
void for_each(Tuple&& x, UnaryFunction f) {
  for_<0,
    tuple_size<
      typename std::remove_const<
        typename std::remove_reference<Tuple>::type
      >::type
    >::value,
    Tuple,
    UnaryFunction>::call(std::forward<Tuple>(x), f);
}

是否有可能通过可变参数模板对此进行概括,以获取任意数量的元组参数?

编辑:

以下是我将如何使用我无法定义的内容:

if (i != e) {
  std::array<Tuple, 2> x;
  std::get<0>(x) = *i;
  std::get<1>(x) = *i;
  ++i;
  std::for_each (i, e, [&x](const Tuple& y) {
    for_each(std::get<0>(x), y, assign_if(std::less));
    for_each(std::get<1>(x), y, assign_if(std::greater));
  });
}

编辑:更改为使用右值引用和std :: forward

3 个答案:

答案 0 :(得分:1)

我不确定这是你的期望,但我会发布它 - 也许有人会发现它有用。

namespace std {
    template<int I, class Tuple, typename F> struct for_each_impl {
        static void for_each(const Tuple& t, F f) {
            for_each_impl<I - 1, Tuple, F>::for_each(t, f);
            f(get<I>(t));
        }
    };
    template<class Tuple, typename F> struct for_each_impl<0, Tuple, F> {
        static void for_each(const Tuple& t, F f) {
            f(get<0>(t));
        }
    };
    template<class Tuple, typename F>
    F for_each(const Tuple& t, F f) {
        for_each_impl<tuple_size<Tuple>::value - 1, Tuple, F>::for_each(t, f);
        return f;
    }
}

函子:

struct call_tuple_item {
    template<typename T>
    void operator()(T a) {
        std::cout << "call_tuple_item: " << a << std::endl;
    }
};

主要功能:

std::tuple<float, const char*> t1(3.14, "helloworld");
std::for_each(t1, call_tuple_item());

答案 1 :(得分:0)

您可以在此处查看我的答案,以获取有关扩展元组的提示

How do I expand a tuple into variadic template function's arguments?

答案 2 :(得分:0)

请参阅下文,了解我将要使用的map(UnaryFunction, Tuple&&...)实现,以及我为了让它完全按照我的需要工作而一直在搞乱的代码(for_aux,{{1}等等。)。

last