尝试在C ++ 14中将元组应用为args

时间:2018-07-16 15:03:50

标签: c++ templates c++14

我正在尝试使用http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3658.html中的apply方法将args元组应用于可调用对象。

这是我的代码:

struct add1_op {
  void operator()(float& dst, float x) const {
    dst = x + 1;
  }
};
struct add_op {
  void operator()(float& dst, float x0, float x1) const {
    dst = x0 + x1;
  }
};

template<class Op>
void f()
{
  float src0[] = {1,2,3};
  float dst[3];

  // my real code has variadic-template parameter packs here
  auto args = std::tuple_cat(std::tuple<float&>(dst[0]),
                             std::tuple<float>(src0[0]));
  apply(Op{}, args);
}

void g()
{
  f<add1_op>();
}

而我正在使用以上论文中的apply

template<typename F, typename Tuple, size_t... I>
auto
apply_(F&& f, Tuple&& args, std::index_sequence<I...>)
  -> decltype(std::forward<F>(f)(std::get<I>(std::forward<Tuple>(args))...))
{
  return std::forward<F>(f)(std::get<I>(std::forward<Tuple>(args))...);
}

// Apply a tuple as individual args to a function
// see: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3658.html
template<typename F, typename Tuple,
         typename Indices = std::make_index_sequence<std::tuple_size<Tuple>::value>>
auto
apply(F&& f, Tuple&& args)
  -> decltype(apply_(std::forward<F>(f), std::forward<Tuple>(args), Indices()))
{
  return apply_(std::forward<F>(f), std::forward<Tuple>(args), Indices());
}

但是c给我这个错误:

apply.cxx:48:3: error: no matching function for call to 'apply'
  apply(Op{}, args);
  ^~~~~
apply.cxx:53:3: note: in instantiation of function template specialization 'f<add1_op>'
      requested here
  f<add1_op>();
  ^
apply.cxx:23:1: note: candidate template ignored: substitution failure [with F = add1_op,
      Tuple = std::__1::tuple<float &, float> &]: implicit instantiation of undefined
      template 'std::__1::tuple_size<std::__1::tuple<float &, float> &>'
apply(F&& f, Tuple&& args)
^

看起来我有一个float&, float元组,这就是我的add1_op的operator()所采用的。所以我不确定为什么会导致替换失败。

1 个答案:

答案 0 :(得分:2)

当您将左值tuple传递给apply时,Tuple将推导为左值引用类型-并且std::tuple_size不接受引用类型。因此,您需要先从Tuple中删除参考性,然后再将其传递给tuple_size

template<typename F, typename Tuple,
         typename Indices = std::make_index_sequence<std::tuple_size<
             std::remove_reference_t<Tuple>>::value>>
auto
apply(F&& f, Tuple&& args)
  -> decltype(apply_(std::forward<F>(f), std::forward<Tuple>(args), Indices()))
{
  return apply_(std::forward<F>(f), std::forward<Tuple>(args), Indices());
}

n3658中建议的实现未实现的事实是一个错误。