【发布时间】:2019-07-06 22:32:33
【问题描述】:
我有以下模板函数(编译器中启用了 C++ 最新标准 - 但也许 17 就足够了)。
#include <functional>
template<typename TReturn, typename ...TArgs>
void MyFunction(const std::function<TReturn(TArgs...)>& callback);
int main()
{
MyFunction(std::function([](int){}));
MyFunction([](int){});
}
当我将第一个调用显式转换为 std::function 时,第一个调用会编译,但第二种情况不会。
在第一种情况下,模板推导是自动完成的,编译器只知道它应该将其转换为某个 std::function 并能够推导参数和返回类型。
但是在第二种情况下,它应该(?)也知道 lambda 应该被转换为一些 std::function,但仍然无法做到。
有没有办法让第二个运行?或者是不是模板根本不进行自动转换?
错误信息是:
错误 C2672:“MyFunction”:找不到匹配的重载函数
错误 C2784: 'void MyFunction(const std::function<_ret> &)': 无法推导出 'const std::function<_ret>
注意:参见“MyFunction”的声明
我的目标是“python 风格的装饰器”。所以基本上是这样的:
template<typename TReturn, typename ...TArgs>
auto MyFunction(std::function<TReturn(TArgs...)>&& callback) -> std::function<TReturn(TArgs...)>
{
return [callback = std::move(callback)](TArgs... args)->TReturn
{
return callback(std::forward<TArgs>(args)...);
};
}
如果我使用模板而不是 std::function,我将如何推导出参数包和返回值?有没有办法通过一些“可调用特征”从可调用对象中获取它?
【问题讨论】:
-
您遇到什么错误?请编辑您的问题以包括它们(完整和完整)。
-
根据用例和设计,您可以通过对可调用对象本身使用单一模板类型来绕过此问题,如
template<typename F> void MyFunction(F callback); -
旁注,不要将 std:: 函数与模板一起使用,使 lambda 类型为模板参数并通过 std::is_invokable (如果相关)进行约束
-
谢谢大家。查看我更新的问题
标签: c++ templates lambda stl template-argument-deduction