С++ remove_if для вектора объектов

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

class vectorList
{

    vector<*myobj> myList; 
};

class myobj
{

    char* myName;
    int index;
    bool m_bMarkedDelete;
}

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

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

Ответ 1

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

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

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

Тогда:

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

Или, используя lambdas:

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 - Функции, которые я написал, конечно, недействительны, поскольку все ваши члены являются закрытыми. Таким образом, вам понадобится доступ к ним.

Ответ 2

Предикат - это в основном условное сравнение. Это может быть функция или объект. Вот пример использования новых С++ lambdas. Этот код будет проходить через вектор и удалять значения, равные 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 у вас не будет lambdas, поэтому вместо функции предиката сравнения или структуры.

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