Usually you can think of a lambda as equivalent to this:
class ANON {
int data;
public:
void operator ()(void) const {
cout << data << endl;
}
} lambda;
// auto lambda = [data]() {cout << data << endl;}
This should give you an idea of how capture is implemented. Capture all (be it by copy =
or reference &
) will probably be no more than syntactic sugar for specifying all used/available variables for capture in the current scope.
But since ...
[..] An implementation may define the closure type differently from what is described below provided this does not alter the observable behavior of the program other than by changing: [..] the size and/or alignment of the closure type [..]
[N4431 §5.1.2/3]
... it would be legal for an implementation to use some sort of "black magic" for capture all by reference lambdas and just use a pointer to the captured stack frame, rewriting accesses to the variables as accesses to some offset of that pointer:
class ANON {
void * stack_frame;
public:
void operator ()(void) const {
cout << *static_cast<int *>(stack_frame + 8) << endl;
}
} lambda;
So using &
might (some day) be more efficient, but as already said this is implementation defined and this nothing to be relied upon.