I can create std::function
that returns std::optional<Foo>
and assigned lambda that returns Foo
to it. Can someone explain in details how this is possible?
simple example:
#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;
}
The constructor of std::optional
(#8 in the overload set) is conditionally explicit, depending on the template parameter. In your case (std::optional<int>
), you can implicitly construct instances,
std::optional<int> opt;
opt = 42; /* No problem, implicit construction. */
and this exactly is what the wrapper std::function<std::optional<int>>
does. It calls the wrapped function, which returns an int
, and uses this return value to implicitly construct its own return value, std::optional<int>
.