std::function<std::optional<T>()> 如何与返回 T 的 lambda 兼容?

How std::function<std::optional<T>()> is compatible with lambda returning T?

我可以创建 std::function returns std::optional<Foo> 并将 returns Foo 的 lambda 分配给它。有人可以详细解释这是怎么可能的吗?

简单示例:

#include <iostream>
#include <optional>
#include <functional>

int main()
{
    int k = 13;
    std::function<std::optional<int>()> f1;
    f1 = [&] {return k++;}; //implicite int
    std::cout<<"k = " << f1().value() << std::endl;
    f1 = [&] () -> int {return k;}; //explicite int
    std::cout<<"k = " << f1().value() << std::endl;
}

constructor of std::optional(重载集中的#8)是条件显式的,具体取决于模板参数。在你的情况下(std::optional<int>),你可以隐式构造实例,

std::optional<int> opt;

opt = 42; /* No problem, implicit construction. */

这正是包装器 std::function<std::optional<int>> 所做的。它调用 return 一个 int 的包装函数,并使用这个 return 值隐式构造它自己的 return 值,std::optional<int>.

存在从 intstd::optional<int> 的隐式转换。

std::function的模板构造函数使用命名要求Callable,只要求INVOKE表达式可以隐式转换为结果类型,而不是相同类型.

简而言之,分配给 std::function 的目标必须是 std::function 的模板参数和 return 类型的 Callable。

例如鉴于:

  • 一个std::function<R(P1, P2)>
  • p1 类型 P1
  • p2 类型 P2

如果 f(p1, p2) 格式正确且可隐式转换为 R,您可以为其分配一个目标 f。 (*)

其他答案表明 std::optional<int> 可从 int 隐式构造。

因此在您的示例中 [&] () -> int {return k;}() return 是一个 int 并且可以隐式转换为 std::optional<int>.

(*) 请注意,这有点过于简单化了,因为严格的定义涉及调用 function/concept