Daily bit(e) C++. std::erase, std::erase_if

Добавлено 3 сентября 2023 в 21:34

Daily bit(e) C++ #215. набор перегрузок, специфичный для контейнеров C++20, для стирания элементов по значению или по предикату: std::erase и std::erase_if.

Daily bit(e) C++. std::erase, std::erase_if

До C++20 удаление элементов из большинства контейнеров на основе их значений или предикатов было двухэтапным процессом.

В C++20 был добавлен набор перегрузок функций, специфичный для контейнеров, std::erase и std::erase_if. Эти функции упрощают двухэтапный процесс до одного вызова и (для версии на основе значения) поддерживают гетерогенные сравнения.

#include <vector>
#include <map>
#include <algorithm>


std::vector<int> data{1,2,3,4,5};

std::erase(data, 3);
// то же самое, что и:
auto it = std::remove(data.begin(), data.end(), 3);
data.erase(it, data.end());
// data == {1, 2, 4, 5}


std::erase_if(data, [](int v) { return v % 2 == 0; });
// то же самое, что и:
it = std::remove_if(data.begin(), data.end(), 
                    [](int v) { return v % 2 == 0; });
data.erase(it, data.end());


// Дополнительно std::erase(_if) возвращает
// количество удаленных элементов:
size_t cnt = std::erase_if(data, [](int v){ return v != 0; });
// cnt == 2, data == {}

// Поддерживается для:
// std::vector, std::deque, std::list,
// std::forward_list, std::string


// Гетерогенное сравнение:
std::vector<std::string> mixed{"hello","this","is","dog"};
std::erase(mixed, "hello");
// "hello" напрямую сравнивается
// с каждым элементом без преобразования
// mixed == {"this", "is", "dog"}


// неупорядоченные и ассоциативные контейнеры
// поддерживают только std::erase_if
std::map<int,int> map{{1,2},{2,3},{3,4}};
std::erase_if(map, [](auto &e) { return e.first < 3; });
// map == {3->4}

// Обратите внимание, что map::erase() уже
// поддерживает гетерогенное удаление-по-значению

Открыть пример на Compiler Explorer.

Теги

C++ / CppDaily bit(e) C++STL / Standard Template Library / Стандартная библиотека шаблоновПрограммирование

На сайте работает сервис комментирования DISQUS, который позволяет вам оставлять комментарии на множестве сайтов, имея лишь один аккаунт на Disqus.com.

В случае комментирования в качестве гостя (без регистрации на disqus.com) для публикации комментария требуется время на премодерацию.