I have used the new range-based for loop provided by C++11 standard and I came up with the following question: suppose that we iterate over a vector<>
usi
You can rely on this behavior as long as vector's capacity is large enough, so reallocation is not required. This would guarantee validity of all iterators and references other than past-the-end iterator after call to push_back()
. This is fine since end()
was calculated only once at the beginning of the loop (see std::vector::push_back).
In your case, you have to increase capacity of test
vector to guarantee this behavior:
vector<unsigned> test({1,2,3});
test.reserve(5);
EDIT
Based on responses to Is it legal to add elements to a preallocated vector in a range-based for loop over that vector?, this is a case of undefined behavior. Release version built with gcc, clang and cl runs fine, but a debug version built with cl (Visual Studio) will throw an exception.
No you cannot rely on this behaviour. Modifying the vector inside the loop results in undefined behaviour because the iterators used by the loop are invalidated when the vector is modified.
The range based for loop
for ( range_declaration : range_expression) loop_statement
is essentially equivalent to
{
auto && __range = range_expression ;
for (auto __begin = std::begin(__range),
__end = std::end(__range);
__begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
When you modify the vector, the iterators __begin
and __end
are no longer valid and the dereferencing __begin
results in undefined behaviour.