у меня есть std::vector<std::shared_ptr<Foo>>
из которого я хочу стереть-удалить элементы, соответствующие некоторому предикату. У удаленных объектов должен быть вызванный метод, который устанавливает некоторый статус для использования в другом месте.
Есть ли причина, по которой я не должен делать это в функции предиката при возвращении true? Это похоже на смешение проблем, но единственные альтернативы, о которых я могу подумать, кажутся гораздо более уродливыми.
Есть две причины, почему это, вероятно, не очень хорошая идея.
Во-первых, большинство стандартных библиотечных алгоритмов не должны использовать предикаты, которые изменяют элементы, на которые они действуют.
Во-вторых, 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