Search code examples
c++lambdac++17std-function

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


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

Solution

  • 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>.