简体   繁体   中英

Forcing C++11 lambda to capture a variable

Suppose copying a variable has a needed side effect. And I want to declare a lambda that copies the variable but doesn't otherwise use the variable. What's the minimum required to do this?

Copiable copyable;

auto lambda1 = [=](){};
auto lambda2 = [copyable](){};
auto lambda3 = [=](){ copyable; }
auto lambda4 = [=](){ volatile copy = copyable; }

lambda1 uses implicit capture, and since the body doesn't mention copyable , I don't believe it actually copies it.

lambda2 uses explicit capture, and it seems according to this , it should capture by copy. Is the compiler allowed to elide the copy? See this for another discussion of this.

lambda3 uses implicit capture but the body mentions copyable . Does this constitute an odr-use of copyable ?

lambda4 uses implicit capture and forces another volatile copy. I'm sure this will actually work, but it's doing more copies than the minimum.

Motivating case: I need to run a cleanup after an arbitrary number of lambda calls are completed, possibly in different threads. I can do this by using a std::shared_ptr with a custom deleter that runs the cleanup, and somehow passing this to each lambda. Then when all the shared ptrs go out of scope, the cleanup will run.

Edit: lambda3 and lambda4 were missing the = for implicit capture.

What's the minimum required to do this?

Explicit capture by value, as in lambda2 .

lambda1 uses implicit capture, and since the body doesn't mention copyable, I don't believe it actually copies it.

That's right. Variables are only implicitly captured if they're odr-used within the lambda.

lambda2 uses explicit capture, and it seems according to this , it should capture by copy.

That's right. Any explicitly captured variables will be captured, whether they're used or not. This is what you want to do to ensure your object is captured.

Is the compiler allowed to elide the copy? See this for another discussion of this.

No. If a variable is captured, then it's captured. The link doesn't really "discuss" that; the only answer confirms that this is the case, with the appropriate wording from the standard.

lambda3 uses implicit capture but the body mentions copyable. Does this constitute an odr-use of copyable?

Yes. The definition of odr-use is

A variable whose name appears as a potentially-evaluated expression is odr-used unless it is an object that satisfies the requirements for appearing in a constant expression and the lvalue-to-rvalue conversion is immediately applied.

and the exception doesn't apply since it isn't constant (and therefore can't appear in a constant expression). (But note that this is ill-formed since there's no default capture.)

lambda4 uses implicit capture and forces another volatile copy. I'm sure this will actually work, but it's doing more copies than the minimum.

Indeed; you're forcing implicit capture by using the value, and forcing an extra copy. That's unnecessary, since lambda2 does what you want.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM