Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding a const function reference to a lambda

Tags:

c++

c++11

lambda

This code

int(&foo)(int, int) = [](int a, int b) { return a + b; };

doesn't compile since apparently a non-const reference can't be initialized with a temporary. Where do I put the const?

like image 292
Artikash-Reinstate Monica Avatar asked Jul 01 '19 04:07

Artikash-Reinstate Monica


2 Answers

As mentioned already, a capture-less lambda is convertible to a function pointer. So if you want to bind that static function to a reference, you need to dereference the pointer.

int(&foo)(int, int) = *[](int a, int b) { return a + b; };

Applying * to the lambda causes a bunch of machinery to kick in. Since the lambda doesn't overload operator*, but does implement a conversion to a pointer type, that conversion happens. Afterwards * is applied to the returned pointer and that yields a function lvalue. That lvalue can then bind to the reference.

Here it is live.

like image 166
StoryTeller - Unslander Monica Avatar answered Oct 04 '22 16:10

StoryTeller - Unslander Monica


A lambda can only be converted to a function pointer if it does not capture.

The closure type for a lambda-expression with no lambda-capture has a public non-virtual non-explicit const conversion function to pointer to function having the same parameter and return types as the closure type’s function call operator. The value returned by this conversion function shall be the address of a function that, when invoked, has the same effect as invoking the closure type’s function call operator

[Lambda Functions][1]

I changed your code as below and it worked.

int (*foo)(int, int)= [] (int a, int b) { return a + b; };
int main()
{
   cout << "Res:: " << foo(10,20);
   return 0;
}

I just make it function pointer.

Alternatively,

auto foo = [](int a, int b) { return a + b; }; 

is also a good choice.

I hope it helps!

like image 32
Abhishek Sinha Avatar answered Oct 04 '22 16:10

Abhishek Sinha