Библиотека C/C++ разработчика | cpp, boost, qt: post #6846 — TG.ME

🥳 Ranges в C++23

C++23 значительно расширил библиотеку Ranges. Рассмотрим важнейшие добавления.


1️⃣ ranges::to — материализация диапазонов

Раньше преобразование view в контейнер было неудобным:

// C++20: нужно было делать так
std::vector<int> v = {1, 2, 3, 4, 5};
auto view = v | views::filter([](int x) { return x > 2; });

std::vector<int> result(view.begin(), view.end()); // громоздко!


C++23 добавляет std::ranges::to:

// C++23: красиво и лаконично
auto result = v
| views::filter([](int x) { return x > 2; })
| std::ranges::to<std::vector>();
// result = {3, 4, 5}

// Можно указать тип элементов явно
auto strs = views::iota(1, 6)
| views::transform([](int x){ return std::to_string(x); })
| std::ranges::to<std::vector<std::string>>();
// strs = {"1", "2", "3", "4", "5"}

// Работает и с другими контейнерами
auto s = some_range | std::ranges::to<std::set>();
auto m = pairs_range | std::ranges::to<std::map>();



2️⃣ Новые адаптеры C++23

views::zip_transform — zip + transform в одном

std::vector<int> a = {1, 2, 3};
std::vector<int> b = {10, 20, 30};

// Попарная сумма
auto sums = views::zip_transform(std::plus{}, a, b);
// 11, 22, 33


views::adjacent — соседние N-ки

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

// Пары соседних элементов
for (auto [a, b] : v | views::adjacent<2>) {
std::cout << "(" << a << "," << b << ") "; // (1,2) (2,3) (3,4) (4,5)
}

// Тройки
for (auto [a, b, c] : v | views::adjacent<3>) {
std::cout << a+b+c << " "; // 6 9 12
}


views::adjacent_transform — скользящая функция

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

// Скользящий максимум из двух соседних элементов
auto sliding_max = v | views::adjacent_transform<2>(
[](int a, int b) { return std::max(a, b); }
);
// 2, 3, 4, 5


views::slide — скользящее окно

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

// Скользящее окно размером 3
for (auto window : v | views::slide(3)) {
for (int x : window) std::cout << x << " ";
std::cout << "| ";
}
// 1 2 3 | 2 3 4 | 3 4 5 |


views::cartesian_product — декартово произведение

std::vector<int> xs = {1, 2};
std::vector<char> ys = {'a', 'b', 'c'};

for (auto [x, y] : views::cartesian_product(xs, ys)) {
std::cout << "(" << x << "," << y << ") ";
}
// (1,a) (1,b) (1,c) (2,a) (2,b) (2,c)



3️⃣ std::generator — корутины как диапазоны

C++23 добавляет std::generator<T> — корутину, которая является диапазоном:

#include <generator> // C++23

std::generator<int> fibonacci() {
int a = 0, b = 1;
while (true) {
co_yield a;
auto next = a + b;
a = b;
b = next;
}
}

// Использование как обычного диапазона!
for (int f : fibonacci() | views::take(10)) {
std::cout << f << " "; // 0 1 1 2 3 5 8 13 21 34
}

// Можно комбинировать с другими адаптерами
auto big_fibs = fibonacci()
| views::filter([](int x) { return x > 100; })
| views::take(5);


❗️Это мощно: теперь можно писать генераторы в естественном императивном стиле, а использовать их — в функциональном стиле через конвейеры.


📍Навигация: ВакансииЗадачи Собесы

Библиотека C/C++ разработчика

#константная_правильность
👍7❤3
July 24, 2026 1.5K 18