我正在使用静态模板成员函数编写一个小类,试图用其参数映射std :: function。
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;
}
};
假设我有这些琐碎的功能:
void f1() { ; }
int f2(int v) { return v; }
double f3(int v1, float v2) { return (double)v1 * (double)v2; }
我想这样调用我的test::exec
函数:
test::exec(f1);
test::exec(f2, 4);
test::exec(f3, 1, 3.14f);
我正在使用Visual Studio,第二种情况(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)'
但是,如果我在模板签名中指定类型,则可以使用:test::exec<int, int>(sq, 4);
显然,我想避免这种情况。另外,我不知道如何用这种语法来表达对f1的调用。
是否可以在不指定模板参数签名的情况下实现这一目标?
答案 0 :(得分:1)
编译器无法推断出std:function
参数和返回类型,因为您根本没有传递exec
和std::function
。
代替std::function
,您可以使exec
接受任意类型的callable(包括函数),并让编译器推断其签名:
template <typename Func, typename... Args>
static double exec(Func func, Args && ... args);
如果您确实需要知道传递给exec
的函数的返回类型,则可以这样做:
template <typename Func, typename... Args>
static double exec(Func func, Args && ... args)
{
using R = decltype(func(args...));
// ...
}
答案改编自@IgorTandetnik的评论。