std :: multiset определяет компаратор для вставки и сравнения - PullRequest
1 голос
/ 25 апреля 2020

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

struct rendererComparator
{
    bool operator ()(const Renderable* r1, const Renderable* r2) const
    {
        return r1->depth < r2->depth;
    }
};

std::multiset<Renderable*, rendererComparator> m_Renderables;

Однако, когда дело доходит до стирания элемента в мультимножестве, вызов erase удаляет все элементы с одинаковой глубиной, что нежелательно. Я попробовал предложения в этом вопросе: В std :: multiset есть функция или алгоритм для удаления только одного образца (единственного или дублирующего), если найден элемент , но

auto iterator = m_Renderables.find(renderable);
if (iterator != m_Renderables.end())
{
    m_Renderables.erase(renderable);
}

Все еще стирает все элементы с одинаковой глубиной из-за компаратора.

Можно ли определить 2 компаратора для std :: multiset без форсирования? ( Как я могу установить два вида компаратора (один для вставки, один для поиска) на этом мультимножестве? ) Один для вставки и один для сравнения?

Спасибо

Edit: Jignatious указал, что я не стирал итератор (опечатка мной). Я решил это с помощью std::find_if

auto iterator = std::find_if(m_Renderables.begin(), m_Renderables.end(), [renderable](const Renderable* r1) { return r1 == renderable; });
if (iterator != m_Renderables.end())
{
    m_Renderables.erase(iterator);
}

1 Ответ

1 голос
/ 25 апреля 2020

Проблема в этой строке:

m_Renderables.erase(renderable);

, которая стирает все элементы с одинаковым значением.

Вам нужно удалить с помощью итератора из вместо этого вызов функции find(). Это сотрет единственный элемент, на который указывает итератор:

m_Renderables.erase(iterator);
...