Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从lambda构造std::函数参数_C++_Templates_Lambda_Stl_Template Argument Deduction - Fatal编程技术网

C++ 从lambda构造std::函数参数

C++ 从lambda构造std::函数参数,c++,templates,lambda,stl,template-argument-deduction,C++,Templates,Lambda,Stl,Template Argument Deduction,我有以下模板函数(编译器中启用了C++最新标准,但可能17个就足够了) #包括 模板 void MyFunction(const std::function和callback); int main() { MyFunction(std::function([](int){})); MyFunction([](int){}); } 当我显式地将第一个调用转换为std::function时,它会编译,但第二个调用不会编译 在第一种情况下,模板推导是自动完成的,编译器只知道它应该将其转换为某个std

我有以下模板函数(编译器中启用了C++最新标准,但可能17个就足够了)

#包括
模板
void MyFunction(const std::function和callback);
int main()
{
MyFunction(std::function([](int){}));
MyFunction([](int){});
}
当我显式地将第一个调用转换为std::function时,它会编译,但第二个调用不会编译

在第一种情况下,模板推导是自动完成的,编译器只知道它应该将其转换为某个std::函数,并且能够推导参数和返回类型

然而,在第二种情况下,它也应该(?)知道lambda应该被转换成一些std::function,但仍然无法这样做

有没有办法让第二个运行起来?或者,对于模板,自动转换根本不会发生

错误消息是:

错误C2672:“MyFunction”:未找到匹配的重载函数

错误C2784:“void MyFunction(const std::function&”):无法推断“const std::function”的模板参数

注:参见“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)...);
    };
}
模板
自动MyFunction(std::function&&callback)->std::function
{
return[callback=std::move(callback)](targets…args)->TReturn
{
返回回调(std::forward(args)…);
};
}
如果我使用模板而不是std::函数,我将如何推断参数包和返回值?有没有办法通过一些“可调用特性”从一个可调用对象获得它

或者,对于模板,自动转换根本不会发生

对。在中不考虑隐式转换

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

这意味着给定的
MyFunction([](int){}),隐式转换(从lambda到
std::function
)将不被考虑,然后
TReturn
TArgs
的推导将失败,调用尝试也将失败

作为解决办法,您可以

  • 如图所示,使用显式转换
  • 正如建议的那样,只需为函子使用一个模板参数。e、 g

    template<typename F>
    auto MyFunction2(F&& callback)
    {
         return [callback = std::move(callback)](auto&&... args)
         {
              return callback(std::forward<decltype(args)>(args)...);
         };
    }
    
    模板
    自动MyFunction2(F&回调)
    {
    return[callback=std::move(callback)](auto&&…args)
    {
    返回回调(std::forward(args)…);
    };
    }
    

  • 你会犯什么错误?请编辑您的问题以包含它们(完整的和完整的)。根据用例和设计,您可以通过为可调用对象本身使用单个模板类型来绕过此问题,如
    模板void MyFunction(F callback)旁注,不要在模板中使用std::函数,将lambda类型设为模板参数,并通过std::is_可调用(相关时)约束它。谢谢大家。请看我更新的问题我将我的问题编辑得更具体一点,我的目标是没有从lambda到
    std::function
    的隐式转换,是吗?但是,存在将非捕获lambda隐式转换为函数指针的过程,而函数指针又可用于初始化
    std::function
    。我弄错了吗?@krzysiekkabowiak std::函数有一个(第五个)函数。@songyuanyao,在我喝完第一杯咖啡之前,我不应该发表评论。我怎么会错过从一个可调用对象(lambda是)构造
    std::function
    ,我使用了很多次,而只想到了通过函数指针来构造呢?现在可以了,谢谢。JVAPen建议使用std::is:invocablem检查类型,但使用static_assert(std::is_invocable::value,“包装的对象必须是invocable”);总是给出false,断言就会失败
    template<typename F>
    auto MyFunction2(F&& callback)
    {
         return [callback = std::move(callback)](auto&&... args)
         {
              return callback(std::forward<decltype(args)>(args)...);
         };
    }