C ++ remove_if по вектору объектов - PullRequest
29 голосов
/ 31 октября 2011

У меня есть вектор (порядок важен) объектов (давайте назовем их классом myobj), где я пытаюсь удалить несколько объектов одновременно.

class vectorList
{

    vector<*myobj> myList; 
};

class myobj
{

    char* myName;
    int index;
    bool m_bMarkedDelete;
}

Я думал, что лучший способДля этого нужно отметить определенные объекты myobj для удаления, а затем вызвать myList.remove_if () для вектора.Однако я не совсем уверен, как использовать предикаты и тому подобное для этого.Должен ли я создать переменную-член в объекте, которая позволяет мне сказать, что я хочу удалить myobj, а затем создать предикат, который проверяет, установлена ​​ли переменная-член?

Как реализовать предикат какчасть класса vectorList?

Ответы [ 2 ]

42 голосов
/ 31 октября 2011

Должен ли я создать переменную-член в объекте, которая позволяет мне сказать что я хочу удалить myobj, а затем создать предикат, который проверяет, установлена ​​ли переменная-член?

Разве вы этого не сделали? Разве это не то, для чего m_bMarkedDelete? Вы бы написали предикат так:

bool IsMarkedToDelete(const myobj & o)
{
    return o.m_bMarkedDelete;
}

Тогда:

myList.erase(
    std::remove_if(myList.begin(), myList.end(), IsMarkedToDelete),
    myList.end());

Или, используя лямбды:

myList.erase(
    std::remove_if(myList.begin(), myList.end(),
        [](const myobj & o) { return o.m_bMarkedDelete; }),
    myList.end());

Если в вашем классе нет этого участника, и вы спрашиваете нас, должен ли он, тогда я бы сказал нет. Какие критерии вы использовали, чтобы решить пометить его для удаления? Используйте те же критерии в своем предикате, например:

bool IndexGreaterThanTen(const myobj & o)
{
    return o.index > 10;
}

note - Написанные мною функции, конечно, недействительны, поскольку все ваши участники являются личными. Так что вам нужен какой-то способ доступа к ним.

10 голосов
/ 31 октября 2011

Предикат - это в основном условное сравнение.Это может быть функция или объект.Вот пример использования новой лямбды C ++.Этот код пройдет вектор и удалит значения, равные 3.

int arg[6] = {1, 2, 3, 3, 3, 5};
std::vector<int> vec(arg, arg+6);
vec.erase(
   std::remove_if(
      vec.begin(), vec.end(),
      [](int i){ return i == 3;}),
   vec.end());

Редактировать: Для указателей, скажем, у вас есть вектор или интерфейсы, для которых вы можете установить их на nullptrзатем удалите их в пакете с почти таким же кодом.В VS2008 у вас не будет лямбда-выражений, поэтому вместо этого создайте функцию или структуру предиката сравнения.

bool ShouldDelete(IAbstractBase* i)
{
    return i == nullptr;
    // you can put whatever you want here like:
    // return i->m_bMarkedDelete;
}

std::vector<IAbstractBase*> vec;
vec.erase(
   std::remove_if(
      vec.begin(), vec.end(),
      ShouldDelete),
   vec.end());
...