Простые приложения на С++
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 делают код компактным, выразительным и удобным для работы с последовательностями данных. Они особенно полезны при создании "ленивых" цепочек операций, которые выполняются по мере необходимости, экономя память и ресурсы.