Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does capturing a variable make the type of a lambda unique? [duplicate]

In the following minimal example:

int main()
{
    const int foo = 1;
    const auto a = foo == 1 ? [](){return 42;} : [](){return 4;};
    const auto b = foo == 1 ? [foo](){return 42;} : [foo](){return 4;};
}

a is fine. b however is not, because:

<source>:5:29: error: incompatible operand types ('(lambda at <source>:5:31)' and '(lambda at <source>:5:53)')

    const auto b = foo == 1 ? [foo](){return 42;} : [foo](){return 4;};
                            ^ ~~~~~~~~~~~~~~~~~~~   ~~~~~~~~~~~~~~~~~~

Why is that the case? And how can the intended b be obtained?

like image 802
Tobias Hermann Avatar asked Jan 26 '23 15:01

Tobias Hermann


2 Answers

Capturing doesn't make the lambda unique; the lambda type is already unique by definition. However, non-capturing lambda's can be converted to function pointers, and that creates a common type in your first example.

You solve your specific example as follows:

const auto b = [foo](){ return (foo == 1) ? 42 : 4;};
like image 156
MSalters Avatar answered Jan 30 '23 22:01

MSalters


Type of lambda is unique even if it does not capture anything. The way you compare them is not correct, you should compare them directly:

auto first{[](){return 42;}};
auto second{[](){return 42;}};
static_assert(not ::std::is_same_v<decltype(first), decltype(second)>);

avoiding possible implicit conversion to pointer to function that happens when automatic deduction of type of variable is performed:

auto a = foo == 1 ? [](){return 42;} : [](){return 4;};
static_assert(::std::is_same_v<int ( * ) (void) , decltype(a)>);
like image 23
user7860670 Avatar answered Jan 30 '23 22:01

user7860670