我有以下模板化函数(在编译器中启用了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(_Types ...)>&)':无法推断'const std :: function <_Ret(_Types ...)>的模板参数
注意:看'MyFunction'的声明
我的目标是“蟒蛇风格装饰”。基本上这个:
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 argument deduction中不会考虑隐式转换。
类型推导不考虑隐式转换(上面列出的类型调整除外):这是重载解析的工作,稍后会发生。
这意味着给定MyFunction([](int){});
,将不考虑隐式转换(从lambda到std::function
),然后TReturn
和TArgs
的推论失败,并且调用尝试也失败了。
作为解决方法,你可以
template<typename F>
auto MyFunction2(F&& callback)
{
return [callback = std::move(callback)](auto&&... args)
{
return callback(std::forward<decltype(args)>(args)...);
};
}