Troskyvs
Troskyvs

Reputation: 8047

C++11: The mutable lambda doesn't seem to change the variable?

I've got a quick test below:

#include<iostream>
using namespace std;
int main(){
    int i=2;
    auto f=[=]()mutable{++i;};
    f();
    f();
    cout<<i<<endl;
    return 0;
}

But the result it still prints "2". Why i is not modified inside a mutable lambda? I'm using clang --std=c++1z.

Thanks!

Upvotes: 3

Views: 702

Answers (3)

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275385

int i=2;
auto f=[=]()mutable{++i;};
f();
f();
std::cout<<i<<std::endl;

this prints 2.

int i=2;
auto f=[&](){++i;};
f();
f();
std::cout<<i<<std::endl;

this prints 4.

int i=2;
auto f=[=]()mutable{++i; std::cout << i << std::endl;};
f();
f();
std::cout<<i<<std::endl;

this prints 3 4 2.

= copies captured data into the lambda.

If mutable the copies can be modified.

& references captured data in the lambda.

Modifying things through references is legal.

[=] is the same as [i], and [&] is the same as [&i] in this context (you can explicitly list captures, or let them be captured implicitly by listing none and using = or &).

Upvotes: 7

songyuanyao
songyuanyao

Reputation: 172904

[=] means you're capturing i by value. Even the mutable lambda could modify it but it's just a copy inside the lambda, then any modification on it would have nothing to do with the original variable.

You might want capture-by-reference, and then mutable is not needed again. e.g.

auto f = [&i]() {++i;};

Upvotes: 3

NathanOliver
NathanOliver

Reputation: 180500

You use [=] for your capture which means the lambda gets a copy of i. This copy is independent from the i in main.

What you need to do is capture by reference [&] in order to apply the changes to the i in main.

Upvotes: 10

Related Questions