从Lambda构造std :: function参数 [英] Constructing std::function argument from lambda

查看:83
本文介绍了从Lambda构造std :: function参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我具有以下模板化功能(在编译器中启用了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?

错误消息是:


错误C2672:'MyFunction':找不到匹配的重载函数

error C2672: 'MyFunction': no matching overloaded function found

错误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"?

推荐答案


还是对于模板来说根本就不会自动转换?

Or can it be that for templates the automatic conversion does not take place at all?

是。在模板参数推论中将不考虑隐式转换。。。 p>

Yes. Implicit conversions won't be considered in template argument deduction.


类型推导不考虑隐式转换(上面列出的类型调整除外):这是超载解析的工作,稍后会发生。

Type deduction does not consider implicit conversions (other than type adjustments listed above): that's the job for overload resolution, which happens later.

这意味着给定 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.

作为解决方法,您可以


  1. 使用您显示的显式转换

  2. 建议的注释,只需使用函子的单个模板参数。例如,

  1. Use explicit conversion as you showed
  2. 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参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆