简体   繁体   English

从lambda构造std :: function参数

[英]Constructing std::function argument from lambda

I have the following templated function (C++ latest standard is enabled in the compiler - but maybe 17 would be enough). 我有以下模板化函数(在编译器中启用了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){});
}

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. 在第一种情况下,模板推导是自动完成的,编译器只知道它应该将它转换为某个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. 但是在第二种情况下它应该(?)也知道lambda应该被转换为某个std :: function,但是仍然无法做到。

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? 或者,对于模板而言,自动转换根本不会发生?

The error message is: 错误消息是:

error C2672: 'MyFunction': no matching overloaded function found 错误C2672:'MyFunction':找不到匹配的重载函数

error C2784: 'void MyFunction(const std::function<_Ret(_Types...)> &)': could not deduce template argument for 'const std::function<_Ret(_Types...)> 错误C2784:'void MyFunction(const std :: function <_Ret(_Types ...)>&)':无法推断'const std :: function <_Ret(_Types ...)>的模板参数

note: see declaration of 'MyFunction' 注意:看'MyFunction'的声明

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)...);
    };
}

If I used a template instead of std::function, the how would I deduce the parameter pack and return value? 如果我使用模板而不是std :: function,我将如何推导出参数包并返回值? 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? 或者,对于模板而言,自动转换根本不会发生?

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. 类型推导不考虑隐式转换(上面列出的类型调整除外):这是重载解析的工作,稍后会发生。

That means given MyFunction([](int){}); 这意味着给定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. ,将不考虑隐式转换(从lambda到std::function ),然后TReturnTArgs失败,调用尝试也失败。

As the workarounds, you can 作为解决方法,你可以

  1. Use explicit conversion as you showed 如您所示,使用显式转换
  2. As the comment suggested, just use a single template parameter for functors. 正如评论所建议的那样,只需使用一个模板参数作为仿函数。 eg 例如

     template<typename F> auto MyFunction2(F&& callback) { return [callback = std::move(callback)](auto&&... args) { return callback(std::forward<decltype(args)>(args)...); }; } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法从lambda函数中推导出模板参数std :: function - Failure to deduce template argument std::function from lambda function 从具有按值捕获的 lambda 移动构造 std::function 时,移动构造函数调用两次 - Move constructor called twice when move-constructing a std::function from a lambda that has by-value captures 使用 lambda 从 std::function 返回类型推导模板参数类型 - template argument type deduction from std::function return type with lambda 调用带有std :: function作为lambda参数的函数 - Call a function with std::function as argument with a lambda Lambda函数作为构造函数中std :: function的默认参数 - Lambda function as a default argument for std::function in constructor 使用lambda作为参数:std :: function或template? - Using lambda as an argument : std::function or template? 用函数构造一个std :: thread - Constructing a std::thread with a function C ++:从模板化方法构造std :: function - C++: Constructing std::function from templated method 使用 std::function 成员从仅移动类型构造元组 - Constructing a tuple from a move only type with a std::function member 从具有可变参数模板构造函数的类型构造 std::function 对象 - constructing a std::function object from a type with a variadic template constructor
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM