4

I want to process elements from a vector for some time. To optimize this I don't want to remove an item when it is processed and I remove all processed items at the end.

vector<Item*>::iterator it;
for(it = items.begin(); it != items.end(); ++it)
{
    DoSomething(*it);

    if(TimeIsUp())
    {
        break;
    }
}

items.erase(items.begin(), it);

Is it safe to use erase when it == items.end()? In documentaion it is said that erase() will erase [first,last) and this should be safe but I want to be sure.

EDIT:

Is it safe to use std::vector.erase(begin(), begin())?

Mircea Ispas
  • 20,260
  • 32
  • 123
  • 211
  • 2
    I strongly advise against using a `vector` of regular pointers. Either use a container specifically designed to hold pointers or use a `vector` of smart pointers. (A possible exception would be if the vector doesn't own the objects it points to.) – David Schwartz Dec 17 '12 at 17:16
  • @Cristy: I don't think that is really a duplicate, the other Q was about a crash because of incrementing an iterator beyond `end`. It only incidentially contains `erase` and `end`, too. – Damon Dec 17 '12 at 17:19
  • I do wonder why the vector can't be `clear`ed, though. – Damon Dec 17 '12 at 17:20
  • @Damon Because `it` may not always be equal to `items.end()` – Praetorian Dec 17 '12 at 17:21
  • @Praetorian: Oh how stupid of me... you're right. I've read "remove all elements afterwards" instead of "removed all **processed** elements". – Damon Dec 17 '12 at 17:25

3 Answers3

5

Yes, this is correct - that's what the notation [first, last) means and end() points one past the end.

djechlin
  • 59,258
  • 35
  • 162
  • 290
3

To answer your edit: yes, that's fine too. vec.erase(q1,q2) is defined as erasing "the elements in the range [q1, q2)." Here, both arguments are the same. [q1, q2) is defined as being a valid range of const iterators. A range is considered to be valid if there is a sequence of increments you can do to q1 to get to q2 - in this case, the sequence has no increments. In fact, the standard specifically defines an empty range:

A range [i,i) is an empty range

Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
1

What that [first,last) means is everything between first and last, including first but not including last. It denotes a half-open set. Had they used [first,last], last would also be included; had they they used (first,last), first and last would be excluded.

There is a problem with your code. You want the element at it to be deleted if it isn't equal to end(). Instead of items.erase (items.begin(),it), you should be using

if (it != items.end()) {
   items.erase (items.begin(), it+1);
}
else {
   items.clear(); // same as items.erase (items.begin(), items.end())
}
David Hammen
  • 32,454
  • 9
  • 60
  • 108