背景:我编写了一个带有一些可调用对象和一个元组的函数,并将元组解压缩到一个可以传递给函数的参数包中。您可以想象这涉及一些模板递归。但是,我的大多数同事都不是C ++的母语使用者,所以他们可以理解代码的问题,以及在错误调用函数时得到的编译错误。
如果我可以生成一个size_t的包,从0到大小为1的大小,我可以使用以下单行:
template <class Function, class... TupleArgs>
auto UnpackTuple(Function fn, std::tuple<TupleArgs>&& t)
-> decltype(fn(std::declval<TupleArgs>()...)) {
return fn(std::get<{my size_t pack}>(std::forward(t))...);
}
有什么东西可以替代“我的size_t包”来完成这项工作吗?我知道如果我认为TupleArgs中的每种类型都是独一无二的,我可以一起破解一些东西,但这是一个非常具体的案例对我没用。
答案 0 :(得分:3)
好像您正在寻找std::apply
,这将完全符合您对UnpackTuple
的要求。
话虽如此,如果你需要手动执行这个奇怪的原因(你可能不应该这样做,除非你想做一些完全不同于调用函数的东西),
std::make_index_sequence
几乎你想要的东西(除了你的size_t
序列被包装在一个类型中,所以你需要一个额外的间接级别)。您可以在cppreference.com上的std::apply
示例实现中看到它是如何使用的: 1)
template <class F, class Tuple, std::size_t... I>
constexpr decltype(auto) apply_impl(F&& f, Tuple&& t, std::index_sequence<I...>)
{
return std::invoke(std::forward<F>(f), std::get<I>(std::forward<Tuple>(t))...);
}
template <class F, class Tuple>
constexpr decltype(auto) apply(F&& f, Tuple&& t)
{
return apply_impl(
std::forward<F>(f),
std::forward<Tuple>(t),
std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<Tuple>>>{}
);
}
由于您提到您仍在使用C ++ 14,因此您需要使用正常的函数调用替换std::invoke
(保留std::forward
,但是,如果有人生气足以实现operator() &&
)
1)(CC-BY-SA 3.0)