Daily bit(e) C++. std::remove, std::remove_if
Daily bit(e) C++ #213, алгоритмы сжатия диапазона: std::remove
и std::remove_if
.
std::remove
и std::remove_if
сжимают диапазон так, чтобы ведущий поддиапазон [begin, last)
не содержал никаких элементов, соответствующих предоставленному значению или для которых предоставленный предикат оценивается как true
.
Количество элементов в базовом диапазоне не изменяется, неудаленные элементы сохраняют свой относительный порядок, а поддиапазон [last, end)
содержит эти элементы в состоянии «перемещено из».
#include <algorithm>
#include <vector>
#include <string>
#include <utility>
std::vector<int> data{1,2,3,4,5};
auto it = std::remove(data.begin(), data.end(), 3);
// [begin, it) содержит неудаленные элементы
auto remainder = std::ranges::subrange(data.begin(), it);
// remainder == {1,2,4,5}
// Версия для диапазонов (начиная с C++20),
// возвращает поддиапазон [it, end)
auto removed = std::ranges::remove_if(remainder,
[](int v) { return v % 2 == 0; });
auto odd = std::ranges::subrange(remainder.begin(), removed.begin());
// odd == {1,5}
// Объект при перемещении устанавливает
// значение своего члена value в "empty"
struct Object
{
Object(std::string value) : value(value) {}
Object(Object&& other) :
value(std::exchange(other.value,"empty")) {}
Object& operator=(Object&& other)
{
value = std::exchange(other.value,"empty");
return *this;
}
std::string value;
};
std::vector<Object> move_semantics;
move_semantics.emplace_back("hello");
move_semantics.emplace_back("this");
move_semantics.emplace_back("is");
move_semantics.emplace_back("dog");
std::ranges::remove_if(move_semantics,
[](auto &e) { return e.value.length() > 4; });
// move_semantics == {{"this"},{"is"}, {"dog"}, {"empty"}}
Открыть пример на Compiler Explorer.