试图在C++14中将元组应用为参数

Trying to apply tuple as args in C++14

本文关键字:元组 应用 参数 C++14      更新时间:2023-10-16

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

这是我的代码:

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());
}

但是clang给了我一个错误:

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()所需要的。所以我不知道为什么这是换人失败。

当您将左值tuple传递给apply时,Tuple将推断为左值引用类型,而std::tuple_size不接受引用类型。因此,在将其传递给tuple_size:之前,您需要从Tuple中剥离参考度

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中建议的实现没有这样做是一个错误。