0

I have a question about calling a lambda function as was described in SO Documentation.

int multiplier = 5;
auto timesFive = [multiplier](int a) { return a * multiplier; }; 
std::cout << timesFive(2); // Prints 10

multiplier = 15;
std::cout << timesFive(2); // Still prints 2*5 == 10

Why doesn't it print 2 * 15 = 30? Clearly, the value of multiplier is being modified and when the call to timesFive is made, it should pick updated value of multiplier.

0

4 Answers 4

3

You need to capture not by value, but by reference:

Just use &multiplier instead of multiplier.

The SO Documentation on Lambda Functions you linked to said:

[] is the capture list. By default, variables of the enclosing scope cannot be accessed by a lambda. Capturing a variable makes it accessible inside the lambda, either as a copy or as a reference. Captured variables become a part of the lambda; in contrast to function arguments, they do not have to be passed when calling the lambda.

int a = 0;                       // Define an integer variable
auto f = [a]()  { return a*9; }; // OK, 'a' is "captured" by value
auto f = [&a]() { return a++; }; // OK, 'a' is "captured" by reference
2

multiplier is captured by value, so it's copied inside the closure object when the lambda function is created.

You can change the multiplier local to the external function however you like, the copy inside the closure will stay at whatever value it was when it was created.

The result you expected is what you would obtain if you captured multiplier by reference, i.e. specifying &multiplier inside the capture list. Notice that in this last case the responsibility of making sure that the lambda does not outlive the variable captured by reference is only yours; as long as your lambda is only local to its containing function it's all fine, but if you return it or store it somewhere else (for example in an std::function variable) and you call it after the parent function returned you get undefined behavior.

1

Capture multiplier by reference:

auto timesFive = [&multiplier](int a) { return a * multiplier; };
0
int multiplier = 5;
auto timesFive = [&multiplier](int a)->int{
    return a*multiplier;
};
cout << timesFive(1) << "\n";
multiplier = 6;
cout << timesFive(2);

The multiplier needs to captured by reference.If you want to capture all the variables you can write

auto timesFive = [&](int  a){return a * multiplier};

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.