Carlos Miguel Colanta Carlos Miguel Colanta - 4 months ago 12
C++ Question

Using lambda expressions by value capture

Quick query regarding usage of lambda captures, particularly about "by value capture". Here is my code:

class carl{
public:
int x;
void sayhi();
};


void carl::sayhi(){

auto c1 = [=](){ //capture by value
std::cout<<&x<<std::endl;
x = 10; // access the copy?
};

c1();
std::cout<<&x<<std::endl; // same address as the one inside lambda
std::cout<<x<<std::endl; //prints 10 now WHY????
}

int main(int argc, char** argv) {

carl x;
x.sayhi();

return 0;
}


My issue is that, are "by value" captures in lambda supposed to affect the original? aren't they supposed to make a copy? From my example, I used
[=]
so my lambda will make a copy of the variable within that class's scope. I tried accessing
x
and it directly altered x's original value. I tried researching about it and from my own words: it's stated that accessing a variable inside a lambda which has a
[=]
capture will access the lambda's local copy.

Edit: I actually get the feeling that I am trying to access
this
pointer which is also captured from
[=]
. Therefore, accessing
x
from my code is like accessing
this->x
which is the same pointer as my original one. Please correct me if I'm wrong.

AnT AnT
Answer

When you are accessing non-static class data members inside lambda, you are actually capturing this pointer by value and accessing the class member as this->x. That means that no local copy of x is made. You are modifying the actual x in the current object.

If fact, if some value is really captured "by value", as a copy, an attempt to modify it will fail. The x = 10 would not even compile if x was really captured by value. You need to declare your lambda as mutable if you want to be able to modify the captured state.