I'm writing a little class using a static template member function trying to map a std::function with its parameters :
class test
{
public:
template <typename R, typename... Args>
static double exec(std::function<R(Args...)> func, Args && ... args) {
func(std::forward<Args>(args)...);
// do something
return 0.0;
}
};
Supposing I have these trivial functions :
void f1() { ; }
int f2(int v) { return v; }
double f3(int v1, float v2) { return (double)v1 * (double)v2; }
I would like to call my test::exec
function like this :
test::exec(f1);
test::exec(f2, 4);
test::exec(f3, 1, 3.14f);
I'm using Visual Studio and I get this error for the second case (f2) :
error C2672: 'test::exec': no matching overloaded function found
error C2784: 'double test::exec(std::function<_Ret(_Types...)>,Args &&...)': could not deduce template argument for 'std::function<_Ret(_Types...)>' from 'int (__cdecl *)(int)'
Nevertheless, it work if I specify the the types in the template signature : test::exec<int, int>(sq, 4);
Obviously, I would like to avoid that. Also, I don't know how to formulate the call to f1 with this syntax.
Is it possible to achieve this goal without specifying the signature of the template parameters?
The compiler can't deduce the std:function
arguments and return type, because you are not passing exec
a std::function
at all.
Instead of a std::function
, you can just make exec
accept an arbitrary type of callable (which includes functions), and let the compiler deduce its signature:
template <typename Func, typename... Args>
static double exec(Func func, Args && ... args);
If you do need to know the return type of the function that you pass to exec
, you can do it like this:
template <typename Func, typename... Args>
static double exec(Func func, Args && ... args)
{
using R = decltype(func(args...));
// ...
}
The answer is adapted from @IgorTandetnik's comments.