Suppose I have a function that returns a std::vector by value:
std::vector<int> buildVector();
It would seem natural to iterate over the result using a range-based for:
for (int i : buildVector()) {
// ...
}
Question: Is it safe to do so?
My reading of the standard (actually, draft n4431) suggests that it might not be, though I'm having a hard time believing that the committee failed to allow for this usage. I'm hoping that my reading is incorrect.
Section 6.5.4 defines the range-based for:
for ( for-range-declaration : expression ) statement
with the following desugaring:
{
auto && __range = range-init;
for ( auto __begin = begin-expr,
__end = end-expr;
__begin != __end;
++__begin ) {
for-range-declaration = *__begin;
statement
}
}
where range-init is just ( expression ), and at least for class types, begin-expr is either __range.begin() or begin(__range), etc.
In my buildVector example, I think the range-init produces a temporary, which the implementation is allowed to destroy immediately after the __range reference is bound. This would mean that the __range reference might already be dangling by the time begin-expr is evaluated.
Certainly, it should always be safe to write this:
std::vector<int> notATemporary = buildVector();
for (int i : notATemporary) {
// ...
}
But I'm hoping I don't have to add this to my list of gotchas.