简体   繁体   中英

Lambda capture reference variable by reference

For a lambda, I'd like to capture something by reference which was held in the outer scope by reference already. Assume that the referenced value outlives the lambda, but not the scope in which the lamdba gets created.

I know that if a lambda captures a reference variable by value , the referenced object will be copied. I'd like to avoid this copy.

But what happens if I capture a reference variable by reference ? What if the original reference variable will get out of scope before executing the lambda? Is this safe? In other words: is the object behind the reference referenced or is the reference variable referenced in the lambda?

auto f() {
    const auto & myRef = g();
    return [&]{ myRef.doSomething(); };
}

f()();  // Safe?

Yes, the key issue in capturing an object by reference is the lifetime of the referenced object, not the lifetime of any intervening references used to get it. You can think of a reference as an alias rather than an actual variable. (And in the type system, references are treated differently from regular variables.) The reference aliases the original object, and is independent of other aliases used to alias the object (other than the fact that they alias the same object).

=====EDIT=====

According to the answer given to this SO question (pointed out by dyp ), it appears that this may not be entirely clear. Throughout the rest of the language, the concept of a "reference to a reference" doesn't make sense and a reference created from a reference becomes a peer of that reference, but apparently the standard is somewhat ambiguous about this case and lambda-captured references may in some sense be secondary, dependent on the stack frame from which they were captured. (The explicit verbiage the SO answer quotes specifically calls out the referenced entity, which would on the face indicate that this usage is safe as long as the original object lives, but the binding mechanism may implicate the capture chain as being significant.)

I would hope that this is clarified in C++14/17, and I would prefer it to be clarified to guarantee legality for this usage. In particular, I think the C++14/17 ability to capture a variable via an expression will make it more difficult to simply capture a scope via a stack-frame pointer and the most sensible capture mechanism would be to generally capture the specific entities individually. (Perhaps a stack-frame-capture could be permitted if an actual local object is captured by reference, since this would result in UB if the lambda is called outside the scope in any event.)

Until we get some clarification, this may not be portable.

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