Удаление элементов от станд. C++:: вектор

Чего надлежащий путь состоит в том, чтобы удалить элементы из вектора C++ при итерации через него? Я выполняю итерации по массиву и хочу удалить некоторые элементы, которые соответствуют определенному условию. Мне сказали, что это - плохая вещь изменить его во время обхода.

Я предполагаю, что должен также упомянуть, что это - массив указателей, которые я должен освободить прежде, чем удалить их.

Править:

Таким образом, вот отрывок моего кода.


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;
  }
}

Я получаю следующую ошибку при компиляции:


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

Извините, я - своего рода C++ newb.

6
задан garsh0p 15 April 2010 в 04:00
поделиться

3 ответа

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
13
ответ дан 8 December 2019 в 02:21
поделиться

То же, что и ответ Брайана Р. Бонди, но я бы использовал функтор, а не указатель на функцию , потому что компиляторы лучше встраивают их:

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

РЕДАКТИРОВАТЬ: В ответ на Если мой вектор содержит указатели, которые необходимо освободить после их удаления, как мне это сделать?

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);
5
ответ дан 8 December 2019 в 02:21
поделиться

Метод вектора erase () возвращает новый итератор, который можно использовать для продолжения итерации:

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;
  }
}
21
ответ дан 8 December 2019 в 02:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: