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?
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
The reasoning is not correct because boo
returns a temporary object by value. Binding this temporary object to a reference implies that the lifetime of the temporary is extended. Standard quote (§ 12.2/5):
[…] 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 […]
The reasoning would be correct if boo
returned a reference. An example for an expression returning a reference to a temporary is string("a") += string("b")
; using this value in a range-based for
loop gives rise to undefined behavior.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With