简体   繁体   中英

Can you pop_back a vector and still use the iterator to the last element?

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());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM