我正在尝试实现一个接受 std::function
的函数它返回一个 it 并可能获得任意数量的参数。
我已经尝试了以下方法,但它无法编译,而且我无法理解错误的含义。
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);
}
我尝试将模板化函数移动到 header ,但它没有用,如果我注释掉 f(int x)
也是如此功能,只留下调用 f
, 我仍然得到 no matching overloaded function found
和 'void ThrowOnError(std::function<int(Args...)>,Args...)': could not deduce template argument for 'std::function<int(Args...)>' from 'int (int)'
这里有什么问题?我在函数中缺少什么?
P.S - 我想要一个需要 std::function
的答案如果可能,不要为仿函数类型添加另一个类型名称。
最佳答案
您没有提供 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();
}
关于带有可变参数 std::function 的 C++11 函数签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40334635/