我正在尝试实现一个函数,它接受std::function
返回它并可能获得任意数量的参数。
我已经尝试了以下但它没有编译,我无法理解错误的含义。
template <typename ...Args>
void ThrowOnError(std::function<int(Args...)> func, Args... args)
{
int err = func(args...);
if (err < 0)
throw std::exception();
}
int f()
{
return 42;
}
int f(int x)
{
return x;
}
int main()
{
ThrowOnError(f);
ThrowOnError(f, 1);
}
我尝试将模板化的函数移动到标题但是它不起作用,如果我注释掉f(int x)
函数并且只留下f
的调用,我仍然得到{{1 }和no matching overloaded function found
这是什么问题?我在功能中缺少什么?
P.S - 如果可能的话,我想要一个'void ThrowOnError(std::function<int(Args...)>,Args...)': could not deduce template argument for 'std::function<int(Args...)>' from 'int (int)'
的答案,而不是为仿函数类型添加另一个类型名称。
答案 0 :(得分:4)
您没有提供std::function
作为参数,也无法进行扣除
在其他地方,要将函数分配给std::function
,您必须知道实际类型。要找到它,必须进行演绎。要进行演绎,您应首先将函数指针指定给std::function
,但后者的类型未知(因为还没有进行演绎)。
所以在一个循环中。
此外,当你这样做时:
ThrowOnError(f);
编译器无法知道您要使用的f
你应该做这样的事情:
ThrowOnError(std::function<int()>{static_cast<int(*)()>(f)});
或者这个(如果您接受为仿函数使用另一个模板参数):
ThrowOnError(static_cast<int(*)()>(f));
通过这种方式,您可以明确地从重载集中选择正确的函数,并且编译器不会猜测您的意图
如上所述,如果您接受修改ThrowOnError
函数,后者将正常工作:
template <typename F, typename ...Args>
void ThrowOnError(F func, Args... args)
{
int err = func(args...);
if (err < 0)
throw std::exception();
}
甚至更好:
template <typename F, typename ...Args>
void ThrowOnError(F &&func, Args&&... args)
{
int err = std::forward<F>(func)(std::forward<Args>(args)...);
if (err < 0)
throw std::exception();
}