Here is a simple solution:
template<class...Args, class F>
void execute(F&& func)
{
using R = std::result_of_t< std::decay_t<F>(Args...) >;
std::packaged_task<R(Args...)> task(std::forward<F>(func));
}
I added perfect forwarding, and the option to pass in arguments. If you don't pass in arguments, it assumes the passed in callable takes 0 arguments.
Example use:
auto func = std::bind([](int x) { return x*x; }, 5);
A name;
name.execute(func);
if func
requires arguments, you have to pass them explicitly. Which is only fair, as it is hard to use a std::packaged_task
without knowing what arguments it will expect. ;)
This also compiles:
auto func = [](int x) { return x*x; };
A name;
name.execute<int>(func);
but how you are going to use that packaged task is tricky.
If you want to mimic the interfaces of std::async
and the like, we can do:
template<class F, class...Args>
void execute(F&& func, Args&&...args)
{
using zF = std::decay_t<F>&&;
using R = std::result_of_t< zF(Args...) >;
std::packaged_task<R()> task(
std::bind( [func=std::forward<F>(func)](auto&&...args)mutable->R{
return std::move(func)(decltype(args)(args)...);
}, std::forward<Args>(args)... )
);
}
which carefully wraps the passed in func
in a lambda in order to avoid calling bind
on bind
, and then binds the arguments passed in.
Now you can:
name.execute([](int x){ return x*x; }, 5);
without using bind
at all.
The code above has not been compiled, and probably contains tpyos.
func
supposed to be called? And what is it supposed to return, if any? – T.C.auto
is not allowed in a parameter declaration. – 0x499602D2auto
is not compliant to C++11. Your use ofdecltype
indicates to me that you do not know what it does. I'm not sure how "in theory this should work" means to you. You have also not understood T.C.s question: thefunc
passed in, how would you expect it to be called? Do you expect to pass it an integer? Nothing? A string? Three chickens and a goat? The result ofstd::bind
doesn't answer the question. – Yakk - Adam Nevraumont