std::vector::erase

Hey guys,

One more vector related question. I searched the erase-remove idiom document for the answer and I don't think I found my answer.

Given vector.erase(vector.begin(), vector.begin() + vector.size() / 2); why would the vector not be half the size after that statement?

Erase should take two iterators in a range and delete that range, to my understanding. The range is: The beginning and the midpoint. Erase it.

I've tried, as a test, just deleting from begin() to end(), and that works fine, so my assumption is that begin() + size() / 2 doesn't evaluate to an a proper iterator. . . ?

Last edited on
As long the size is an even number your code should remove exactly half of the element.
It works, not sure what you did.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <vector>

using namespace std;

int main()
{
  vector<int> v = { 1, 2, 3, 4, 5, 6, 7, 8 };

  v.erase(v.begin(), v.begin() + v.size() / 2);

  cout << "vector size: " << v.size() << "\n";
  cout << "Elems: ";
  for (const int i : v)
    cout << i << " ";
}

Ouput:
vector size: 4
Elems: 5 6 7 8 
@Peter This is exactly what I thought as well. I even tried casting the division to int to potentially cut off any decimal portion, and it still isn't working as I expect.

The code is part of a bigger statement aimed at randomly erasing (killing) half of a population after it has reached critical mass, due to starvation.

The whole segment looks like,

1
2
3
4
5
6
7
8
9
10
11
{
  const int STARVATIONTHRESHOLD = 1000;

  if(colony.size() > STARVATIONTHRESHOLD)
  {
    std::random_shuffle(colony.begin(), colony.end());
    colony.erase(colony.begin(), colony.begin() + static_cast<int>(colony.size()/2));
  }

  std::cout << "New population: " << size();
}


I figure if I first shuffle them, then delete half, I've randomly killed half the population.
@Thomas Hmm, I dunno, I guess it's a problem with peripheral code. . .
You are printing size(), not colony.size().
@Peter Sorry, that's just a reference to an unseen function size() is actually just a wrapper for colony.size() in the class. I can replace it, and same result.
Are you sure the size is ever above the threshold? I noticed you have no space or anything after printing the size so you might want to make sure you are not printing a number right after so that it looks like the size is much bigger than it really is.
It's likely being erased fine and somehow repopulated later in the call stack... I'll keep poking.
The casting is unnecessary since vector.size() returns a size_t (an unsigned value) and the 2 is an int, so you already have integer math.

And by the way is there a reason you're "erasing" the first half of the vector instead of the last half? Deleting the last half will be much more efficient.

And don't forget about he affect erase has on iterators (invalidation).

Deleting the last half will be much more efficient.
And much easier to write too.
 
colony.resize(colony.size() / 2);
Topic archived. No new replies allowed.