如何切片可变参数模板参数并使用它们?
How can I slice variadic template parameters and use them?
我对模板元编程还很陌生。这就是我想做的。
template <typename... Args>
void to_be_async_func(Args&&... args)
{
//want to use args[0...N-2] to invoke a function call
//and args[N-1(last)] to use a handler function after the prior call.
}
int main()
{
int a = 5;
int b = 3;
to_be_async_func(a, b, [](int res)
{
//do something with the result
//any Callable can be passed
});
}
最初我试过
template<typename... Args, typename Callable>
void to_be_async_func(Args&&... args, Callable op)
{
}
但是在这种情况下 "Callable" 应该有默认值才能像那样使用。
在我看来,某种辅助模板结构可能会做到这一点。
如果这件事可行,你能告诉我路吗?
提前谢谢你。
编辑
我也看过 this post 并按照说明尝试了。
有效。但是正如文中所述,我想知道是否有更标准的方法来实现这一点。
使用 std::index_sequence
似乎是可行的方法:
template <typename F, typename... Args>
void to_be_async_func_first(F&& f, Args&&... args)
{
std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
}
template <std::size_t ... Is, typename... Args>
void to_be_async_func_impl(std::index_sequence<Is...>, Args&&... args)
{
auto&& args_tuple = std::forward_as_tuple(std::forward<Args>(args)...);
to_be_async_func_first(std::get<sizeof...(Args) - 1>(args_tuple),
std::get<Is>(args_tuple)...);
}
template <typename... Args>
void to_be_async_func(Args&&... args)
{
to_be_async_func_impl(std::make_index_sequence<sizeof...(Args) - 1>(),
std::forward<Args>(args)...);
}
我对模板元编程还很陌生。这就是我想做的。
template <typename... Args>
void to_be_async_func(Args&&... args)
{
//want to use args[0...N-2] to invoke a function call
//and args[N-1(last)] to use a handler function after the prior call.
}
int main()
{
int a = 5;
int b = 3;
to_be_async_func(a, b, [](int res)
{
//do something with the result
//any Callable can be passed
});
}
最初我试过
template<typename... Args, typename Callable>
void to_be_async_func(Args&&... args, Callable op)
{
}
但是在这种情况下 "Callable" 应该有默认值才能像那样使用。
在我看来,某种辅助模板结构可能会做到这一点。
如果这件事可行,你能告诉我路吗?
提前谢谢你。
编辑
我也看过 this post 并按照说明尝试了。
有效。但是正如文中所述,我想知道是否有更标准的方法来实现这一点。
使用 std::index_sequence
似乎是可行的方法:
template <typename F, typename... Args>
void to_be_async_func_first(F&& f, Args&&... args)
{
std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
}
template <std::size_t ... Is, typename... Args>
void to_be_async_func_impl(std::index_sequence<Is...>, Args&&... args)
{
auto&& args_tuple = std::forward_as_tuple(std::forward<Args>(args)...);
to_be_async_func_first(std::get<sizeof...(Args) - 1>(args_tuple),
std::get<Is>(args_tuple)...);
}
template <typename... Args>
void to_be_async_func(Args&&... args)
{
to_be_async_func_impl(std::make_index_sequence<sizeof...(Args) - 1>(),
std::forward<Args>(args)...);
}