如何从 lambda 推导出返回类型?

Kwa*_*wan 4 c++ lambda templates

这是示例代码

#include <iostream>

template<typename T>
T foo(T(*fp)())
{
    return fp();
}


int main()
{
    std::cout<<foo([]->int{ return 1; });
}
Run Code Online (Sandbox Code Playgroud)

当我编译上面的代码时,编译器说它不能推导出模板参数,但我已经指定了 lambda 的返回类型。

son*_*yao 7

foo需要函数指针,而你传递一个lambda,但隐式转换(从lambda来函数指针)将不被视为模板参数推导T,这使得调用失败。

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

您可以明确指定模板参数:

foo<int>([]()->int{ return 1; });
// ^^^^^
Run Code Online (Sandbox Code Playgroud)

或通过operator+或将 lambda 转换为函数指针static_cast

foo(+[]()->int{ return 1; });
//  ^
foo(static_cast<int(*)()>([]()->int{ return 1; }));
//  ^^^^^^^^^^^^^^^^^^^^^^                    ^
Run Code Online (Sandbox Code Playgroud)

顺便说一句:与尾随返回类型一起使用的省略参数列表是 C++23 lambda功能。(所以我添加了()s。)正如@max66 所建议的,没有尾随返回类型,lambda 也可以正常工作;将自动推导出返回类型,例如foo(+[]{ return 1; });.

  • @AdrianMole max66 是的,它是 C++23 [lambda](https://en.cppreference.com/w/cpp/language/lambda) 功能。*省略参数列表:函数不带参数,就像参数列表是 ()。仅当未使用 constexpr、consteval、可变、异常规范、属性或尾随返回类型时,才能使用此形式。(直到 C++23)* (2认同)