Удалите элементы из vector и мутируйте те, которые удалены

У меня есть std::vector<std::shared_ptr<Foo>> из которого я хочу стереть-удалить элементы, соответствующие некоторому предикату. Удаленные объекты должны иметь метод, который задает определенный статус, для использования в другом месте.

есть ли причина, по которой я не должен делать это в функции предиката, когда возвращается true? Это немного похоже на смешение проблем, но единственные альтернативы, которые я могу придумать, кажутся намного уродливее.

1 ответов


есть две причины, почему это не хорошая идея.

во-первых, большинство стандартных алгоритмов библиотеки не должны использовать предикаты, которые изменяют элементы, на которые они действуют.

во-вторых,std::remove и std::remove_if Не давайте вам хороший набор "удаленных" элементов*. Вы можете полагаться только на элементы, которые выбраны для сохранения. "Удаленные "элементы на самом деле могут быть копиями" хороших". И поскольку вы храните общие указатели, они могут быть указывая на те же объекты, что и" хорошие " элементы.

альтернативой было бы использовать std::partition, затем повторите соответствующий раздел раздела, затем используйте erase аналогично идиоме стирания-удаления.

auto p = std::partition(v.begin, v.end(), pred);
std::for_each(p, v.end(), call_method_functor);
v.erase(p, v.end());

* эти алгоритмы, вероятно, должны были быть названы keep и keep_if