Why lambda capture by copy has the same external variable address

I was checking old code I tried with lambda and I noticed. If I specify the lambda capture as a copy and change the value inside it, it changes that variable since it was a reference.

void classV::setLambda() {
  r.setLambda([=]() {
      value = 100;
      v = 10;
      std::cout << &value << std::endl;
  });
}
void classV::executeLambda() {
    r.runLambda();
    std::cout << "NVAL: " << value << std::endl;
    std::cout << "NVAL: " << v << std::endl;
    std::cout << &value << std::endl;
}

      

Basically, this code stores the lambda on an external object (class instance) and is executed there, I imagined that by specifying the capture as a copy, when I tried to get the value of those variables, it shouldn't change ... how it was copied.

But this is not the case, both values ​​and v are 100 and 10. To be specific, value is a static int of classV, and v is an attribute of an int object of class V.

Why are these values ​​changing ?, I checked the addresses inside the lambda and executeLambda and they are the same, won't it only happen if it was captured by a link? I guess I missed something.

+3


source to share


1 answer


[=]

copies by value and you expect to have a different address for local value

.

However, C ++ makes an exception to member variables. They are still accessed through this

. So your code is equivalent to writing:

r.setLambda([=]() {
    this->value = 100;
    this->v = 10;
    std::cout << &(this->value) << std::endl;
});

      

And this

is a pointer, so it stays the same with copy by value.

The solution would be to write



r.setLambda([=,value]()

      

but you cannot commit member variables.

You need to write:

auto valueCopy = value;
r.setLambda([=]()
    // ... use valueCopy here.

      

My advice: try to avoid the default modes , as you will end up with unexpected or forgotten behavior on the same day.

+1


source







All Articles