I wonder what happens if I have an iterator on the last element of the vector and do pop_back
.
std::set<int> s;
s.insert(5);
std::vector<int> v = {1, 2, 3, 4, 5};
for (auto it = v.begin(); it != v.end();) {
if (s.count(*it)) {
std::swap(*it, v.back());
v.pop_back();
} else {
++it;
}
}
Code above works properly (v
is {1, 2, 3, 4}
after that block) at least with clang, but is it correct to check if it == v.end()
if it
is invalidated?
Your instincts are good; vector::pop_back
invalidates iterators and references to the last element. If it
is such an iterator, then it will be invalidated, and thus cannot be compared with v.end()
.
It would be much better to fix this by using algorithms and the erase-remove idiom:
auto last_it = std::remove_if(v.begin(), v.end(), [&](const auto &val) {return s.count(val) != 0;});
v.erase(last_it, v.end());
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