У меня есть вектор (порядок важен) объектов (позволяет вызывать их класс 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());