Reputation:
I'm quite new to template metaprogramming. This is what I wanted to do.
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
});
}
Initially I tried like
template<typename... Args, typename Callable>
void to_be_async_func(Args&&... args, Callable op)
{
}
However in this case "Callable" should have default value to be used like that.
In my opinion, some kind of helper template struct might do this.
If this thing is possible, could you please show me the way?
Thank you in advance.
EDIT
I've also seen this post and tried as instructed.
It worked. But as stated in the text, I want to know if there's a more standard way to achieve this.
Upvotes: 0
Views: 468
Reputation: 218238
Using std::index_sequence
seems the way to go:
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)...);
}
Upvotes: 1