Public Group

# What is the type of a Lambda with capture?

This topic is 496 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Premise: this question is just out of curiosity, I don't need to use this knowledge, therefore answers like "you don't need to do it" or "just use auto" are invalid. This is for science

The code below compile:

#include <iostream>
using namespace std;

int(*myFunction(int b))(int a)
{
int(*f)(int a) = [](int a) { int myVariable = a ; return ++myVariable; };
return f;
}

int main()
{
while (true){
cout << myFunction(5)(12);
}
}

Now if I change the lambda to capture b, the code doesn't compile anymore, code below:

int(*myFunction(int b))(int a)
{
int(*f)(int a) = [b](int a) { int myVariable = a + b; return ++myVariable; };
return f;
}

so my question is, what does the lambda type being assigned to "f" when I add the capture changes into?

How would you re-write "int(*f)(int a)" such that it compiles when there is that capture of "b"? (no auto, typedef, using or other tricks allowed, I want to see the ugly form )

Edited by MarcusAseth

##### Share on other sites

The type is anonymous. Only the compiler knows it, there's no way to determine what it is. A lambda with a capture tends to compile down to something like:

// this
auto f = [a](int x) -> int
{
return x + a + 2;
};

// turns into this
struct
{
int a;

int operator()(int x)
{
return x + a + 2;
}
} f {a};

You can't use a function pointer type to refer to a lambda with a capture. std::function will allow you to do what you're trying to do:

std::function<int(int b)> myFunction(int a)
{
std::function<int(int b)> = [](int a) { int myVariable = a ; return ++myVariable; };
return f;
}

Otherwise... Just use auto.

Edited by Oberon_Command

##### Share on other sites
1 minute ago, Oberon_Command said:

Just use auto.

I see, thanks

##### Share on other sites

I think you're starting to bump against the reason the standards committee had to accept the updated version of auto.  People had been pushing for it for years, but to get all the lambda functionality in required some unnamable types. The simpler versions generate an anonymous class with a functor, meaning operator(), which gives the result.

Lambdas without a capture can be converted to a function pointer. That is guaranteed in the standard, and easy enough to figure out how to mimic with function objects like @Oberon_Command did above.  The compiler generates them as anonymous objects, but you could do it yourself.

Lambdas with a capture can sometimes be converted, but sometimes not. When you start dealing with captures there are edge cases that I never really understood that made it impossible to think of as a regular function object.  These cannot be generated with an actual type in C++, they are unnameable, so they were called Lambda Closures and can only be referred to with auto.  Their actual type is basically "block of code".

Since nobody can actually name what the type is, you've got to use auto.

##### Share on other sites
4 minutes ago, frob said:

Since nobody can actually name what the type is, you've got to use auto.

Which is also less headache, so I don't complain

1. 1
2. 2
3. 3
Rutin
15
4. 4
khawk
13
5. 5
frob
12

• 9
• 9
• 11
• 11
• 23
• ### Forum Statistics

• Total Topics
633664
• Total Posts
3013238
×