TGViewer
Библиотека C/C++ разработчика | cpp, boost, qt Библиотека C/C++ разработчика | cpp, boost, qt @cppproglib · 16.9K subscribers
Post #6684 1.52K
🍳 Ranges: другие полезные адаптеры

В прошлый раз мы разобрали views::join и views::join_with — «сплющивание» вложенных диапазонов. Сегодня — подборка адаптеров, которые пригождаются постоянно, но о которых часто забывают.


🍒 views::reverse — обратный порядок

std::vector<int> v = {1, 2, 3, 4, 5};
for (int x : v | views::reverse) {
std::cout << x << " "; // 5 4 3 2 1
}


❗️ Требует bidirectional_range. Например, views::filter моделирует bidirectional_range, только если исходный диапазон сам bidirectional_range и common_range — так что для vector, deque или list цепочка views::filter(...) | views::reverse работает, а для forward_list или istream_view — нет.


🏝 views::keys и views::values — для пар и map

std::map<std::string, int> ages = {{"Алиса", 30}, {"Борис", 25}};

for (const auto& name : ages | views::keys) {
std::cout << name << "\n"; // Алиса, Борис
}

for (int age : ages | views::values) {
std::cout << age << "\n"; // 30, 25
}


Под капотом views::keys — это views::elements<0>, а views::valuesviews::elements<1>. Работает с любым диапазоном, элементы которого моделируют std::pair или std::tuple-подобный тип.


🍍 views::elements<N> — N-й элемент tuple/pair

std::vector<std::tuple<int, std::string, double>> records = {
{1, "Alice", 3.14},
{2, "Bob", 2.71},
};

// Берём только строки (индекс 1)
for (const auto& s : records | views::elements<1>) {
std::cout << s << "\n"; // Alice, Bob
}


Обобщённая версия keys/values — извлекает элемент с индексом N из каждого кортежа. Индекс задаётся на этапе компиляции, поэтому выход за границы — ошибка компиляции, а не UB.


🍕 views::counted — N элементов начиная с итератора

std::vector<int> v = {10, 20, 30, 40, 50};
auto it = v.begin() + 1; // указывает на 20

// 3 элемента начиная с позиции 1
auto three = views::counted(it, 3);
// 20, 30, 40


В отличие от views::take, который работает с диапазоном, counted принимает итератор + количество. Это незаменимо, когда у вас «голый» итератор без парного end — например, указатель указатель на элемент C-массива или результат std::find.

❗️ Ответственность за то, что it + n не выходит за пределы, лежит на вас — проверки в рантайме нет.


🍿 views::all — обернуть в view явно

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

// views::all явно создаёт view из контейнера
auto all_view = views::all(v);

// Это полезно при передаче в функции, ожидающие view


Зачем нужен, если | и так оборачивает? Бывает полезно при передаче контейнера в функцию, которая принимает viewable_range, или для хранения view в переменной без auto&&. На практике views::all вызывается неявно почти в каждой цепочке — но иногда явный вызов делает код яснее.


🍋 views::common — сделать begin/end одного типа

Многие «классические» алгоритмы и конструкторы контейнеров ожидают, что begin() и end() возвращают один и тот же тип. У ленивых view это часто не так — end() может вернуть sentinel, а не итератор.

auto view = some_range | views::filter(...);

// Если нужно передать в старый алгоритм, требующий итераторов одного типа:
auto common_view = view | views::common;
std::copy(common_view.begin(), common_view.end(), output);


❗️ Если диапазон уже common_range, адаптер ничего не делает — просто пробрасывает как есть. Накладных расходов в этом случае ноль.


🩹 Комбинируем всё вместе

std::map<std::string, std::vector<int>> data = {
{"alpha", {1, 2, 3}},
{"beta", {4, 5}},
{"gamma", {6, 7, 8, 9}},
};

// Все значения → сплющить → обратный порядок → первые 4
auto result = data
| views::values
| views::join
| views::reverse
| views::take(4);

for (int x : result) {
std::cout << x << " "; // 9 8 7 6
}


Ни одного промежуточного контейнера — каждый элемент протягивается через всю цепочку лениво, по требованию.


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

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

#константная_правильность
  • ❤ 7
  • 👍 2
More from @cppproglib
  1. Sep 19, 2026А вы уже забрали свой подарок ко Дню программиста? К вашему профессиональному празднику Tp…
  2. Sep 18, 2026От исходного кода до процессора: разберись, как работает программа 💻 Стартует практически…
  3. Sep 15, 2026😭 Как не потратить недельный лимит AI-кодинга за три дня? Разберём на вебинаре, как трати…
  4. Sep 13, 2026🤪 Если бы можно было задать один вопрос про AI в разработке — что бы вы спросили? Как выб…
  5. Sep 13, 2026🤩 Inline static в классах — забудь про .cpp Сколько раз ты забывал добавить определение s…
  6. Sep 13, 2026🌸 Вселенная намекает: пора уже начать этот курс С 14 сентября цены в Proglib Academy выра…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →