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<>
using the range-based for
, and we add some element in the end of the vector during this iteration. Thus, when do the loop end?
For instance, see this code:
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<unsigned> test({1,2,3});
for(auto &num : test) {
cout << num << " ";
if(num % 2)
test.push_back(num + 10);
}
cout << "\n";
for(auto &num : test)
cout << num << " ";
return 0;
}
I tested G++ 4.8 and Apple LLVM version 4.2 (clang++) with "-std=c++11" flag, and the output is (for both):
1 2 3
1 2 3 11 13
Note that the first loop terminates in the end of original vector, although we add other elements to it. It seems that the for-range loop evaluate the container end in beginning only. Is this, in fact, the correct behavior of range-for? Is it specified by the committee? Can we trust in this behavior?
Note that if we change the first loop by
for(vector<unsigned>::iterator it = test.begin(); it != test.end(); ++it)
with invalid the iterators and come up with a segmentation fault.
Range-based for loop (since C++11) Executes a for loop over a range. Used as a more readable equivalent to the traditional for loop operating over a range of values, such as all elements in a container.
To add elements to vector, you can use push_back() function. push_back() function adds the element at the end of this vector. Thus, it increases the size of vector by one.
Add Elements to a Vector Here, the push_back() function adds elements 6 and 7 to the vector. Note: We can also use the insert() and emplace() functions to add elements to a vector.
Use the range-based for statement to construct loops that must execute through a range, which is defined as anything that you can iterate through—for example, std::vector , or any other C++ Standard Library sequence whose range is defined by a begin() and end() .
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.
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