Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing elements from C++ std::vector

Tags:

c++

vector

What is the proper way to remove elements from a C++ vector while iterating through it? I am iterating over an array and want to remove some elements that match a certain condition. I've been told that it's a bad thing to modify it during traversal.

I guess I should also mention that this is an array of pointers that I need to free before removing them.

EDIT:

So here's a snippet of my code.


void RoutingProtocolImpl::removeAllInfinity()
{
  dv.erase(std::remove_if(dv.begin(), dv.end(), hasInfCost), dv.end()); 
}

bool RoutingProtocolImpl::hasInfCost(RoutingProtocolImpl::dv_entry *entry)
{
  if (entry->link_cost == INFINITY_COST)
  {
    free(entry);
    return true;
  }
  else
  {
    return false;
  }
}

I'm getting the following error when compiling:


RoutingProtocolImpl.cc:368: error: argument of type bool (RoutingProtocolImpl::)(RoutingProtocolImpl::dv_entry*)' does not matchbool (RoutingProtocolImpl::)(RoutingProtocolImpl::dv_entry)'

Sorry, I'm kind of a C++ newb.

like image 771
meteoritepanama Avatar asked Apr 15 '10 03:04

meteoritepanama


People also ask

Can you remove elements from a vector in C++?

clear() removes all the elements from a vector container, thus making its size 0. All the elements of the vector are removed using clear() function.

How do I remove multiple elements from a vector in C++?

If you need to remove multiple elements from the vector, the std::remove will copy each, not removed element only once to its final location, while the vector::erase approach would move all of the elements from the position to the end multiple times. For Example, Consider removing all elements < 5 in following vector.

How do I erase an element from std :: vector <> by value?

You need to use std::remove algorithm to move the element to be erased to the end of the vector and then use erase function. Something like: myVector. erase(std::remove(myVector. begin(), myVector.

How do you pop an element from a vector in C++?

C++ pop_back() function is used to pop or remove elements from a vector from the back. The value is removed from the vector from the end, and the container size is decreased by 1.


3 Answers

The vector's erase() method returns a new iterator that can be used to continue iterating:

std::vecor<MyClass> v = ...;
std::vecor<MyClass>::iterator it = v.begin();
while (it != v.end()) {
  if (some_condition(*it)) {
    it->cleanup(); // or something
    it = v.erase(it);
  }
  else {
    ++it;
  }
}
like image 111
sth Avatar answered Oct 26 '22 22:10

sth


bool IsEven (int i) 
{ 
  return (i%2) == 0; 
}

//...

std::vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.erase(std::remove_if(v.begin(),v.end(),IsEven), v.end()); 
//v now contains 1 and 3
like image 37
Brian R. Bondy Avatar answered Oct 26 '22 23:10

Brian R. Bondy


Same as Brian R. Bondy's answer, but I'd use a functor rather than a function pointer because compilers are better at inlining them:

struct IsEven : public std::unary_function<int, bool>
{
    bool operator()(int i) 
    { 
      return (i%2) == 0; 
    };
}

//...

std::erase(std::remove_if(v.begin(),v.end(),IsEven()), v.end());

EDIT: In response to If my vector is of pointers that need to be freed after they are removed, how would I do this?

struct IsEven : public std::unary_function<int, bool>
{
    bool operator()(int i) 
    { 
      return (i%2) == 0; 
    };
}

struct DeletePointer : public std::unary_function<myPointedType *, void>
{
    void operator()(myPointedType * toDelete)
    {
        delete toDelete;
    };
}

//...

typedef std::vector<something>::iterator Iterator_T;
Iterator_t splitPoint = std::partition(v.begin(),v.end(),IsEven());
std::for_each(v.begin(), splitPoint, DeletePointer());
v.erase(v.begin(), splitPoint);
like image 44
Billy ONeal Avatar answered Oct 27 '22 00:10

Billy ONeal