2012-03-29 2 views
1

В следующей ситуации, как удалить экран из списка?Удалить объект из std :: list

class ScreenManager { 

    list<GameScreen> screens; 

    void removeScreen(GameScreen & screen) { 
     //screens.remove(screen); // won't work 
     //screens.erase(remove(screens.begin(), screens.end(), screen), screens.end()); // won't work either 
    } 
} 
+0

Почему это не работает? – vmpstr

+5

'remove' работает. Если нет, то вы не говорите нам достаточно. –

+0

Дайте нам более подробную информацию, можете ли вы предоставить больше кода? – ManiP

ответ

2

Использовать список :: найти, чтобы найти итератор на экране, который вы действительно хотите удалить. Затем используйте remove, передавая ему итератор.

+2

'remove' не принимает итератор, что вы имеете в виду' erase'. Но 'find', за которым следует' erase', это именно то, что делает 'remove', поэтому мне интересно, кто это проголосовал. –

2

Метод std :: list's erase принимает итератор, который вы хотите удалить. Поэтому, как только вы получите итератор на свой экран, просто передайте его на экраны.

Другими словами, вы хотите сделать screens.erase(std::find(screens.begin(), screens.end(), screen)); Это будет работать, только если у вас есть правильный оператор == в вашем классе значений.

Обратите внимание, что если вы планируете много удалять, вы можете использовать что-то вроде std :: map вместо std :: list (так как поиск вашего экрана в списке будет O (n).)

+3

На самом деле, всякий раз, когда мой фрагмент работает, remove тоже должен работать ... так что ваша проблема, вероятно, в том, что вам нужно переопределить operator ==. –

+0

Не могли бы вы объяснить, что мне нужно делать с оператором и почему? – Ben

+0

Ответ Йоханнеса S здесь. По сути, удалить нужно знать, какой объект в вашем списке тот, который вы ищете, и C++ не дает ему способ сделать это, если вы не скажете ему, как (переопределив оператор ==). Другой вариант - иметь список , «новый» все ваши объекты и просто скопировать указатели. Тогда remove/find просто использует равенство указателя. Но есть и много проблем с этим :-) –

11

std::remove (или std::list::remove в вашем случае) использует оператор сравнения (operator==), чтобы найти/идентифицировать объект, который следует удалить из контейнера.

Поскольку вы используете определенный пользователем тип GameScreen, вам необходимо предоставить operator== для вашего класса. Так, в своем классе вы должны реализовать:

bool operator==(const GameScreen& other) const { 
    // do whatever you need to determine whether 
    // `GameScreen` instance `other` is equal (in value) 
    // to `this` instance of `GameScreen` 
} 

Затем screens.remove(screen); будет работать.

+0

@Ben Это решило вашу проблему? –

Смежные вопросы