function templates and lambdas

Hi,

I tried to use a function template to encapsulate a lambda expression in
order to call it recursivly. It turned out I wasn't able to use
"=" as lambda initializer, but only "&".
I tried to figure out (stack modell) why this was the case,
without much success.

Can someone please explain why I need to use "by reference (&)" here?

Here a little example:

1
2
3
4
5
6
7
8
9
   function<int(int, int)>gcd =
	[&](int a, int b) ->int
	{
	if (a < b)    return gcd(b,a);
	int rem(a%b);
	if (0 == rem) return b;
		
	return gcd(b, rem);
	};


Thanks.
I think it is a similar problem as trying to have a recursive type
1
2
3
4
struct A
{
	A a;
};

This can't work because A contains an A which contains an A ... it never stops. The size would be be infinite. Same with the lambda if you use [=]. A lambda that contains a lambda that contains a lambda ... . That is why I think you have to capture the lambda by reference.
Last edited on
The joys of self-referencing initialization

In the right side of the statement function<>gcd = , the name "gcd" is defined, but refers to the uninitialized block of memory, the object before its constructor has been called.

In the [&] case you bind a reference to that not-yet-living object. Once gcd's constructor finishes, that reference is valid, so that when you, later on, call the function, it correctly calls itself.

In the [=] case, you tell the constructor of the lambda to store a *copy* of the object named "gcd" inside the lambda. And that's what it does: it calls the std::function's copy constructor, giving it the uninitialized std::function (a bunch of random bytes, essentially) as the argument, and that copy constructor crashes at runtime on my gcc. The debugger confirms that the crash occurred in std::function<int(int, int)>::function(const std::function<int(int, int)> &).

@Peter87: an std::function is a container object, which holds a pointer to its target function. It's not like struct A{A a;};, it's more like struct A{vector<A> v;};
Last edited on
Thanks.
That clears it up very well!
Topic archived. No new replies allowed.