You can remove from vector based on predicate (condition):
std::vector<int>::iterator it = std::remove_if( // it shifts, doesn't
v.begin(), v.end(), // reduces the physical size
[](int i){ return i > 2; } ));
and erase unneeded values:
v.erase( it, v.end()); // this is needed as remove_if doesn't erase
// elements that don't meet condition (are not to be
// removed), it simply moves those that don't meet
// condition to the begin.
// now we reduce the physical size
Why remove_if is followed by erase
Removing is done by shifting (by means of move assignment) the
elements in the range in such a way that the elements that are not to
be removed appear in the beginning of the range. Relative order of the
elements that remain is preserved and the physical size of the
container is unchanged. Iterators pointing to an element between the
new logical end and the physical end of the range are still
dereferenceable, but the elements themselves have unspecified values
(as per MoveAssignable post-condition). A call to remove is typically
followed by a call to a container's erase method, which erases the
unspecified values and reduces the physical size of the container to
match its new logical size.
http://en.cppreference.com/w/cpp/algorithm/remove
Example
// Let's imagine your vector is
v = { 1, 2, 3, 4, 5};
^ ^
begin end
// copy( v.begin(), v.end(), ostream_iterator<int>(cout));
will print: 12345
after remove_if vector becomes:
v = { 1, 2, 3, 4, 5};
^ ^ ^
begin it end
// copy( v.begin(), v.end(), ostream_iterator<int>(cout));
// will still print a vector of size 5: 12345
// but
// copy( v.begin(), it, ostream_iterator<int>(cout));
will print: 12
after v.erase( it, v.end()); vector becomes:
v = { 1, 2};
^ ^
begin end
// copy( v.begin(), v.end(), ostream_iterator<int>(cout));
will print: 12
compiled example
C++03:
bool f(int i) { return i > 2; }
std::vector<int>::iterator it = std::remove_if( v.begin(), v.end(), f); // shifts
v.erase( it, v.end()); // reduces the physical size