0

I have the following, which does not compile:

void func(std::optional<std::function<void(int, int)>> arg1)
{
    return;
}

void callee(bool flag)
{
    auto arg1 = [](int a1)
    {
        return;
    };

    auto arg2 = [](int a1)
    {
        return;
    };

    func(
        (!flag ? std::optional{arg2} : (flag ? std::optional{arg1} : std::nullopt)), 
        std::optional{arg2});    
}

int main(int argc, char **argv) {
    callee(true);
}

For the following reason:

error: operands to '?:' have different types 'std::optional<callee(bool)::<lambda(int)> >' and 'std::optional<callee(bool)::<lambda(int)> >'

Explicitly defining the type of either arg1 or arg2 instead of using auto allows this to compile.

Why is the compiler unable to deduce that they are in fact the same type?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Tyler Kelly
  • 564
  • 5
  • 23
  • Lambda is syntax sugar over class with `operator()`, so each lambda is in fact its own unique type, even if they are identical. – Yksisarvinen Apr 20 '23 at 16:00
  • BTW, you have *"typo"*, 2 args expected for `std::function`, but 1 args for each lambda. – Jarod42 Apr 20 '23 at 16:02
  • 2
    "_Explicitly defining the type of either arg1 or arg2 instead of using auto allows this to compile._": It is impossible to explicitly specify the type of the `arg1`/`arg2` variables in their definition. "_Why is the compiler unable to deduce that they are in fact the same type?_": They are not. – user17732522 Apr 20 '23 at 16:02
  • why use ternary ? `if (condition) func(a); else func(b);` poses no artificial restictions upon `a` and `b`. The ternary is not just a tool to make code shorter – 463035818_is_not_an_ai Apr 20 '23 at 16:10
  • 1
    A three-legged conditional with a boolean condition seems a bit excessive. (You basically have `if (!flag) {...} else if (flag) {...} else {...}` – molbdnilo Apr 20 '23 at 16:19
  • 1
    Your conditional is strange: the `nullopt` case will never be triggered. So if you really want to use a conditional you could do `func(std::optional{flag ? arg1 : arg2});`. – cigien Apr 20 '23 at 16:20

1 Answers1

2

lambda is not std::function. You have 2 different lambdas (even if code is identical), and so 2 different types.

Jarod42
  • 203,559
  • 14
  • 181
  • 302