简体   繁体   中英

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

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

There is an implicit conversion from int to std::optional<int> .

The template constructor of std::function uses the named requirement Callable , which only requires that the INVOKE expression be implicitly convertible to the result type, not that they be the same type.

In short the target assigned to std::function must me Callable for the parameters and return type of the template parameter of std::function .

Eg Given:

  • a std::function<R(P1, P2)>
  • p1 of type P1
  • p2 of type P2

You can assign a target f to it if f(p1, p2) is well-formed and implicitly convertible to R . (*)

The other answers show that std::optional<int> is implicitly constuctible from int .

So in your example [&] () -> int {return k;}() returns an int and that is implicitly convertible to std::optional<int> .

(*) Please note that this is a bit oversimplified as the rigorous definition involves the invoke function/concept

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM