Jump to content
  • Advertisement
Sign in to follow this  
noatom

C++11 lambda, modifying copied value

This topic is 1196 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

int fooVar = 10;
 std::function<void()> fooFunction =  [=]() {
 fooVar = 12;
};

Trying to modify foorVar in that lambda results in an error, because its not an lvaue.

 

Why is the copied value made constant?! 

Share this post


Link to post
Share on other sites
Advertisement
Because const data is safer than mutable data. This also makes the lambda more composable. And C++ says so.

As well as to try to prevent people from making the same mistake you've made in your example code - assuming that the change you made in the lambda is visible outside the lambda because the variable has the same name even though it's a completely different value.

What's the point of modifying a value that no one can see? The only one who can read your changed fooVar is the lambda itself, the external fooVar will be untouched because you captured by value.

If you absolutely want the copy to be mutable, you can add the mutable flag to it. But you should generally avoid doing that as other people may not expect a function to return different results when given the same parameters. Edited by SmkViper

Share this post


Link to post
Share on other sites

It makes sense if you want to do something like:

int counter = 10;
std::function<void()> fooFunction = [=]() {
    while(counter--) {
        // do important things
    }
}

Share this post


Link to post
Share on other sites

It makes sense if you want to do something like:

But in your example, there is no reason for counter to exist outside the lambda. It always starts at 10 and always ends at 0. So counter could always exist entirely in the lambda.

[Edit]
Or pass it as a parameter. Since it isn't actually modifying counter, it is modifying a copy of counter.

Share this post


Link to post
Share on other sites


But in your example, there is no reason for counter to exist outside the lambda. It always starts at 10 and always ends at 0.

Assuming counter isn't defined as int counter = 10; but is something dynamic. Does your argument still hold?

Share this post


Link to post
Share on other sites

Assuming counter isn't defined as int counter = 10; but is something dynamic. Does your argument still hold?

In a sense, yes. You're not actually manipulating counter, but a copy of counter. The type is irrelevant. It doesn't need to be captured by the lambda, just passed as a parameter. Which for readability would make more sense (in my mind), since that defines it as an input affecting the function.

You probably don't want to be capturing everything by value anyway, as this could be very expensive.

Share this post


Link to post
Share on other sites

If you mark the lambda is mutable, the operator() will not be marked const, so you can modify the fooVar member.


int fooVar = 10;
std::function<void()> fooFunction =  [=]()mutable {
 fooVar = 12; // totally fine now!
};

Keeping in mind, of course, that this happens, because it was copied by value:

fooFunction();
assert(fooVar == 12, "Huh?"); // this fires - function didn't modify this variable

Share this post


Link to post
Share on other sites


If you mark the lambda is mutable, the operator() will not be marked const, so you can modify the fooVar member.

 

But also note that if you do this, you'll need to be very careful about how many times fooFunction is invoked (since the second invocation won't behave identically to the first), as well as if the functor itself it is ever copied, or only ever referenced (and if copied, whether the copy happens before or after any invocations).

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!