Библиотека C/C++ разработчика | cpp, boost, qt

@cppproglib
🍿 C++ Ranges. Views и алгоритмы Продолжаем тему Ranges в C++. В библиотеке Ranges есть два главных инструмента работы с последовательностями: 1. std::ranges::* алгоритмы — переработанная версия классической библиотеки <algorithm>. Принимают не пару итераторов, а целый диапазон, поддерживают проекции и лучше взаимодействуют с современными типами. 2. std::views::* адаптеры — ленивые обёртки над диапазонами. Не копируют данные, а описывают как их обойти. Удобны для цепочек преобразований. 🐤 Старый стиль vs новый стиль std::vector<int> v = {5, 3, 1, 4, 2}; // Старый стиль: передаём пару итераторов std::sort(v.begin(), v.end()); // Новый стиль: передаём весь диапазон std::ranges::sort(v); ❗️Разница кажется небольшой, но новый стиль: • Синтаксически короче • Поддерживают проекции — сортировку по произвольному полю объекта • Работают с любым range-совместимым типом, не только с контейнерами ✅ Пример 1. Cортировка #include <algorithm> #include <vector> #include <iostream> int main() { std::vector<std::string> names = {"Boris", "Anton", "Victor", "Anna"}; std::ranges::sort(names); for (const auto& name : names) { std::cout << name << "\n"; } // Anna, Anton, Boris, Victor } ✅ Пример 2. Проекции — сортировка по полю структуры Одна из главных фич ranges-алгоритмов. Не нужно писать лямбду вручную — достаточно указать, по какому полю сортировать: #include <algorithm> #include <vector> #include <iostream> #include <string> struct Person { std::string name; int age; }; int main() { std::vector<Person> people = { {"Boris", 30}, {"Anna", 25}, {"Victor", 35} }; // Сортируем по возрасту, передав &Person::age как проекцию std::ranges::sort(people, {}, &Person::age); for (const auto& p : people) { std::cout << p.name << " " << p.age << "\n"; } // Anna 25, Boris 30, Victor 35 } ✅ Пример 3. Views — ленивые цепочки std::views не трогают исходный контейнер и не создают копий — они описывают трансформацию, которая применяется при обходе: #include <ranges> #include <vector> #include <iostream> int main() { std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8}; // Берём только чётные, умножаем на 10, берём первые 3 auto result = v | std::views::filter([](int x) { return x % 2 == 0; }) | std::views::transform([](int x) { return x * 10; }) | std::views::take(3); for (int x : result) { std::cout << x << "\n"; } // 20, 40, 60 } ❗️Исходный вектор v не изменился. Весь пайплайн вычисляется лениво — только когда мы итерируемся в цикле. 🐸 Продолжение следует... В следующий раз разбираем pipelines
Если у вас установлено приложение,
вы можете сразу перейти в канал