Простые приложения на С++
January 18
Диапазоны (Ranges) в C++20
Диапазоны (Ranges) в C++20 представляют собой мощное дополнение к стандартной библиотеке, которое упрощает работу с последовательностями данных, делая код более выразительным и читаемым. Они предоставляют новый способ обработки контейнеров и других последовательностей, используя ленивую (отложенную) оценку и модульный подход.
Основные концепции и возможности диапазонов
- Композиция операций
 Диапазоны позволяют комбинировать операции (например, фильтрацию, трансформацию) без промежуточных контейнеров.
- Ленивая оценка
 Операции над диапазонами выполняются только тогда, когда это необходимо (например, при итерировании).
- Совместимость со стандартными контейнерами
 Диапазоны могут быть использованы с контейнерами STL (например,std::vector,std::list).
- Модули из <ranges>
 Все функции и классы диапазонов находятся в заголовочном файле<ranges>.
- Адаптеры диапазонов
 Диапазоны поддерживают адаптеры, такие какstd::views::filter,std::views::transform, которые могут комбинироваться в цепочки.
Основные компоненты диапазонов
- std::ranges::view
 Представляет объект, который можно перебирать.
 Пример:- std::views::filter,- std::views::transform.
- std::ranges::algorithm
 Диапазоны интегрированы с алгоритмами STL, такими как- std::ranges::sort,- std::ranges::for_each.
- std::views
 Пространство имен, содержащее адаптеры представлений (views).
Примеры кода :
#include <iostream>
#include <vector>
#include <ranges>
int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    // Фильтрация четных чисел
    auto even_numbers = numbers | std::views::filter([](int n) { return n % 2 == 0; });
    // Печать результата
    for (int n : even_numbers) {
        std::cout << n << " ";
    }
    return 0;
}#include <iostream>
#include <vector>
#include <ranges>
int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    // Умножение каждого элемента на 2
    auto doubled = numbers | std::views::transform([](int n) { return n * 2; });
    for (int n : doubled) {
        std::cout << n << " ";
    }
    return 0;
}3. Композиция операций (фильтрация + трансформация)
#include <iostream>
#include <vector>
#include <ranges>
int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    // Четные числа, умноженные на 3
    auto result = numbers 
                  | std::views::filter([](int n) { return n % 2 == 0; })
                  | std::views::transform([](int n) { return n * 3; });
    for (int n : result) {
        std::cout << n << " ";
    }
    return 0;
}4. Диапазоны с алгоритмами std::ranges
#include <iostream>
#include <vector>
#include <ranges>
#include <algorithm>
int main() {
    std::vector<int> numbers = {5, 3, 9, 1, 4, 8};
    // Сортировка с использованием std::ranges::sort
    std::ranges::sort(numbers);
    for (int n : numbers) {
        std::cout << n << " ";
    }
    return 0;
}
5. Ограничение диапазона (Take и Drop)
#include <iostream>
#include <vector>
#include <ranges>
int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    // Взять первые 5 элементов
    auto first_five = numbers | std::views::take(5);
    // Пропустить первые 3 элемента
    auto skip_three = numbers | std::views::drop(3);
    std::cout << "First 5: ";
    for (int n : first_five) {
        std::cout << n << " ";
    }
    std::cout << "\nAfter skipping 3: ";
    for (int n : skip_three) {
        std::cout << n << " ";
    }
    return 0;
}#include <iostream>
#include <vector>
#include <ranges>
int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    // Обратить порядок элементов
    auto reversed = numbers | std::views::reverse;
    for (int n : reversed) {
        std::cout << n << " ";
    }
    return 0;
}Диапазоны выполняют вычисления только при необходимости.
#include <iostream>
#include <ranges>
int main() {
    auto infinite_range = std::views::iota(1); // Бесконечный диапазон от 1
    // Взять первые 10 элементов из бесконечного диапазона
    auto first_ten = infinite_range | std::views::take(10);
    for (int n : first_ten) {
        std::cout << n << " ";
    }
    return 0;
}
Итог
Диапазоны в C++20 делают код компактным, выразительным и удобным для работы с последовательностями данных. Они особенно полезны при создании "ленивых" цепочек операций, которые выполняются по мере необходимости, экономя память и ресурсы.