What is the lifetime of the range-init in a range-based for loop?

c++, c++11, for-loop, language-lawyer, lifetime

Solution

Is this reasoning correct? If not, why not?

It is correct up until this point:

And so the temporary return value of boo() is destroyed at the end of the statement "auto&&r=boo()" [...]

Binding a temporary to a reference extends its lifetime to be that of the reference. So the temporary lasts for the whole loop (that's also why there is an extra set of `{}` around the whole construct: to correctly limit the lifetime of that temporary).

This is according to paragraph 5 of §12.2 of the C++ standard:

The second context is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference except:

[various exceptions that don't apply here]

This is an interesting property that allows abusing the ranged-for loop for non-rangey things: http://ideone.com/QAXNf

Problem

In the latest C++ standard it implies that: ``` for (foo : bar) baz; ``` is equivilant to: ``` { auto && r = bar; for ( auto it = r.begin(), end = r.end(); it != end; ++it ) { foo = *it; baz; } } ``` When bar in the above is a function call that returns a collection, eg: ``` vector<string> boo(); ``` ie ``` for (auto bo : boo()) ... ``` Doesn't the line become: ``` auto&& r = boo(); ... ``` And so the temporary return value of `boo()` is destroyed at the end of the statement `auto&& r = boo()`, and then r is a hanging reference at the entry of the loop. Is this reasoning correct? If not, why not?

Original source