Добрый день, всем привет!
Снова в эфире рубрика «Вы не спрашивали, но мы отвечаем», раздел «Программирование», глава «Что нового я узнал в сейчас лет».
Например, не так давно я узнал, что std::unordered_map
не сортирует данные в отличие от std::map
. А много-много лет назад (в 2007-м году) нам пришлось реализовывать бинарный поиск, чтобы ускорить вставку элементов в std::map
(там жил кэш текстур) вместо того, чтобы взять std::unordered_map
. Наш просчёт немного оправдывает то, что мы были молоды, неопытны и std::unordered_map
появился в стандарте C++11 спустя несколько лет после описываемых событий.
Вообще, я не отношусь к тем людям, которые ежедневно читают свежайший стандарт C++, подчеркивая карандашиком важные места. Скорее, я начинаю читать стандарт, когда нужно найти решение текущей задачи. Так, например, я совершенно случайно наткнулся на std::enable_shared_from_this
, когда просматривал код нашего проекта, поминая тимлида нехорошими словами . Там был метод типа make() у класса, который должен вернуть std::shared_ptr
от экземпляра этого класса. Если вы наследуете класс от std::enable_shared_from_this
, то у вас появляется метод shared_from_this()
, и дело в шляпе. Нужно только помнить, что метод shared_from_this()
можно вызвать только у объекта, который уже управляем std::shared_ptr
иначе будет исключение.
Каких-то одиннадцать лет назад я написал статью про эффективное удаление элементов массива. Тогда единственный способ, который я знал, выглядел следующим образом:
Вся упомянутая в статье магия с перемещением в конец массива и удалением происходит в puf()
.
Оказывается, есть метод лучше, и имя ему — std::remove_if
. Этот метод перемещает в начало элементы, для которых условие ложно, возвращая итератор на конец массива с элементами, для которых условие истинно. Эксперимент показал, что после итератора лежит мусор.
С новыми знаниями, удаление элементов из контейнера будет выглядеть так:
Что является более продвинутым вариантом и пишется короче, с чем я вас и поздравляю!
Обратите внимание, методы std::remove
и std::remove_if
не удаляют элементы, удаление происходит после вызова std::erase
.