За последние 15 лет ситуация в C ++ сильно изменилась.В июле 1994 года предложение Александра Степанова о библиотеке, включающей его идеи общего программирования, получило окончательное одобрение комитета ANSI / ISO.Эта библиотека, которую мы обычно называем сегодня STL, впоследствии стала стандартной библиотекой C ++.История STL столь же увлекательна, как и идеи, стоящие за ней, и она определенно стоит того, чтобы ее прочитать.
Функция std::remove_if()
, которую вы нашли, является еще одним отражением этой философии, ставшей частью современного C ++.идентичность.Короче говоря, это универсальная функция, которая будет работать с любым контейнером (последовательностью) элементов и с любым (действующим как) условием.Для этого вы должны предоставить функции две вещи:
- пару итераторов , которые разграничивают диапазон элементов, над которыми вы хотите работать;
- и предикат , который при вызове элемента возвращает true, если элемент должен быть удален, и false в противном случае.
Как выясняется, в этом случае предикат, который вы хотитеэто равенство.А поскольку удаление элементов, основанных на равенстве, является такой распространенной задачей, стандарт также предоставляет функцию std::remove()
, которая предполагает неявный предикат равенства.Конечно, вы должны убедиться, что элементы могут сравниваться:
bool operator==(const MyClass& a, const MyClass& b)
{
// return true if the two are equal, and false otherwise.
}
Затем мы можем использовать наш предикат для удаления элементов типа MyClass
:
std::remove(things.begin(), things.end(), *this); // if *this == elem
Напомним, что стандартная функцияstd::remove()
работает с любым контейнером, даже с теми, которые еще не были созданы.Поскольку каждый вид контейнера имеет свой собственный способ удаления элементов, эта функция не может действительно выполнить удаление, не зная деталей реализации контейнера, в котором она работает.Таким образом, вместо этого функция std::remove()
меняет элементы так, что «удаленные» элементы находятся в конце контейнера.Затем он возвращает итератор, указывающий на первый элемент «удаленных» последовательных элементов.
typedef std::list<MyClass>::iterator iter;
iter first_removed = std::remove(things.begin(), things.end(), *this);
Наконец, мы действительно удаляем элементы, вызывая функцию удаления конкретного контейнера, которая работает в одной позиции всписок или ряд последовательных элементов для удаления:
things.erase(first_removed, things.end());
Весьма часто можно увидеть код такого рода в одной строке:
things.erase(std::remove(things.begin(), things.end(), *this),
things.end());
Все это может показаться подавляющим исложный, но у него есть несколько преимуществ.С одной стороны, этот дизайн стандартной библиотеки поддерживает динамическое программирование.Это также позволяет стандартной библиотеке предлагать контейнеры с очень тонкими интерфейсами, а также несколько бесплатных функций, которые работают с различными типами контейнеров.Это позволяет быстро создать контейнер и мгновенно получить все возможности стандартной библиотеки для работы с ним.Кроме того, он позволяет быстро написать универсальную функцию, которая мгновенно работает со всеми стандартными контейнерами - уже написанными и еще не написанными.