A simple std::vector
std::vector<int> integers;
integers.push_back(10);
integers.push_back(11);
cout << "Before: " << integers.size(); //prints 2
I tried using 3 different versions of code to erase each element one by one C++5.1 and C++14
Version 1:
for( std::vector<int>::iterator it = integers.begin() ; it != integers.end() ; )
{
cout << "\nVal: " << *it;
it = integers.erase(it);
}
cout << "\nAfter: " << integers.size();
Output: [Expected]
Before: 2
Val: 10
Val: 11
After: 0
Version 2 in C++14:
for( std::vector<int>::iterator it1, it = integers.begin() ; it != integers.end() ; )
{
cout << "\nVal: " << *it;
it1 = std::next(it);
integers.erase(it);
it = it1;
}
Output: [Unexpected]
Before: 2
Val: 10
After: 1
While for std::map, version 2 works as expected:
int main() {
std::map<int, int> m;
m.insert(make_pair(10, 11));
m.insert(make_pair(12, 13));
cout << "Before: " << m.size();
for( std::map<int, int>::iterator it1, it = m.begin() ; it != m.end() ; )
{
cout << "\nVal: " << it->first << ", " << it->second;
it1 = std::next(it);
m.erase(it);
it = it1;
}
cout << "\nAfter: " << m.size();
return 0;
}
Outputs:
Before: 2
Val: 10, 11
Val: 12, 13
After: 0
Even this works :
for( std::map<int, int>::iterator it1, it = m.begin() ; it != m.end() ; )
{
cout << "\nVal: " << it->first << ", " << it->second;
m.erase(it++);
}
Why version 2 works on std::map but not on std::vector?
The difference is that
std::vector
iterators are invalidated after erasing an element while for associative containers (23.2.4 Associative container)