问题描述
我具有以下模板化功能(在编译器中启用了C ++最新标准-但也许17足够了。)
I have the following templated function (C++ latest standard is enabled in the compiler - but maybe 17 would be enough).
#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时,但是第二种情况
The first call compiles, when I explicitly convert it to std::function, but the second case does not.
在第一种情况下,模板推导是自动完成的,编译器只知道将其转换为某种std :: function并能够推导参数和返回类型。
In the first case the template deduction is done automatically, the compiler only knows that it shall convert it to some std::function and able to deduce the parameter and return type.
但是,在第二种情况下,它也应该知道将lambda转换为某些std :: function,但仍然无法执行。
However in the second case it shall(?) also know that the lambda shall be converted to some std::function, but still unable to do it.
是否有一种解决方案可以使第二个运行?还是对于模板来说根本就不会自动转换?
Is there a solution to get the second one running? Or can it be that for templates the automatic conversion does not take place at all?
错误消息是:
错误C2784:'void MyFunction(const std :: function< _Ret(_Types ...)>&)' :无法推断出const std :: function< _Ret(_Types ...)>的模板参数
error C2784: 'void MyFunction(const std::function<_Ret(_Types...)> &)': could not deduce template argument for 'const std::function<_Ret(_Types...)>
注意:请参见'MyFunction'的声明
note: see declaration of 'MyFunction'
我的目标是 python样式装饰器。因此基本上是这样的:
What I am aiming for is a "python style decorator". So basically this:
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,我将如何推导参数包并返回价值?是否可以通过某些可调用特征从可调用对象中获取它?
If I used a template instead of std::function, the how would I deduce the parameter pack and return value? Is there some way to get it from a callable via some "callable traits"?
推荐答案
是。在中将不考虑隐式转换。。。 p>
Yes. Implicit conversions won't be considered in template argument deduction.
这意味着给定 MyFunction([](int){});
,不会考虑转换(从lambda到 std :: function
),然后扣除 TReturn
和 TArgs
失败,调用尝试也失败。
That means given MyFunction([](int){});
, the implicit conversion (from lambda to std::function
) won't be considered, then the deduction for TReturn
and TArgs
fails and the invocation attempt fails too.
作为解决方法,您可以
- 使用您显示的显式转换
-
以,只需使用函子的单个模板参数。例如,
- Use explicit conversion as you showed
As the comment suggested, just use a single template parameter for functors. e.g.
template<typename F>
auto MyFunction2(F&& callback)
{
return [callback = std::move(callback)](auto&&... args)
{
return callback(std::forward<decltype(args)>(args)...);
};
}
这篇关于从Lambda构造std :: function参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!