1

I am writing code that passes references to lambda expressions so I decided to check out a few simple examples using g++-7

The code:

int i = 2;
auto f = [i]() {
    printf("i = %d\n", i);
};
printf("incrementing i to  %d\n", ++i);
f();

Prints

incrementing i to  3
i = 2

as expected because the lamda make a copy of i for later and:

int i = 3;
int& j = i;
auto g = [j]() {
    printf("j = %d\n", j);
};
printf("incrementing i to  %d\n", ++i);
g();

prints

incrementing i to  4
j = 3

yet:

i = 4;
int* k = &i;
auto h = [k]() {
    printf("*k = %d\n", *k);
};
printf("incrementing i to  %d\n", ++i);
h();

prints

incrementing i to  5
*k = 5

Now normally references behave like pointers that do not need to be dereferenced (and cannot be changed) but with lamda capture this is not the case. Is this standard expected behaviour and if so why does this differ from normal reference behaviour?

6502
  • 112,025
  • 15
  • 165
  • 265
doron
  • 27,972
  • 12
  • 65
  • 103
  • References don't behave like pointers, they behave like the objects they refer to. `[j](){}` is exactly the same as `[i](){}`. – molbdnilo Aug 26 '17 at 17:49
  • The real thing you haven't managed to understand yet has nothing to do with lambdas but with references. I've recently wrote [a small explanation](https://stackoverflow.com/a/45825892/6639082) which, I hope, will let you understand C++ references better. – WindyFields Aug 26 '17 at 18:05

2 Answers2

3

Unless you use & in the capture, a lambda expression captures by value. Regardless of whether you capture i or j, unless you use &i or &j, the variable is captured by value.

That is no different than a regular function.

void foo(int i) {}
void bar(int& i) {}

int i;
int& j = i;

foo(i); // Passed by value
foo(j); // Passed by value also.

bar(i); // Passed by reference
bar(j); // Passed by reference also.
R Sahu
  • 204,454
  • 14
  • 159
  • 270
0

To pass i as a reference use

auto f = [&i]() {
  printf("i = %d\n", i);
};

(Note the & prefix in the capture)

It doesn't matter wether i was originally declared as a reference or not.

jederik
  • 352
  • 2
  • 7