Перейти к содержанию

Диапазоны и представления (C++20)

Начало урока

Диапазоны и представления (C++20)

Компонуемые, ленивые конвейеры над вашими данными

Главная идея: Библиотека Ranges (C++20, заголовок <ranges>) позволяет описать преобразование данных как конвейер из небольших компонуемых шагов, соединённых оператором конвейера |. Каждый шаг — это представление (view): лёгкий, не владеющий данными объект, который описывает, как получать элементы, и вычисляет их лениво — по одному, только когда вы выполняете обход. Вы уже знаете контейнеры STL, итераторы, алгоритмы и лямбды; диапазоны склеивают их в читаемые конвейеры и убирают шумные пары begin()/end().
К концу вы сможете:
  • объяснить, что такое диапазон и представление и почему представления дёшевы и ленивы,
  • строить конвейеры с помощью адаптеров диапазонов, таких как filter, transform, take и drop,
  • использовать проекцию, чтобы направить алгоритм диапазонов на одно поле объекта,
  • рассуждать о владении и времени жизни, чтобы избегать «висячих» представлений.

1. От пар итераторов к диапазонам

Классические алгоритмы STL принимают пару итераторов. Чтобы отфильтровать, преобразовать и напечатать контейнер, вы жонглируете begin()/end(), промежуточными контейнерами и написанными вручную циклами:

// классический C++17: три прохода, один временный вектор
std::vector<int> evens;
std::copy_if(v.begin(), v.end(), std::back_inserter(evens),
             [](int n){ return n % 2 == 0; });
std::vector<int> squared;
std::transform(evens.begin(), evens.end(), std::back_inserter(squared),
               [](int n){ return n * n; });

Диапазон — это просто всё, что можно обойти: он предоставляет begin() и end(). Каждый стандартный контейнер является диапазоном. C++20 добавляет ограниченные алгоритмы в пространстве имён std::ranges, которые принимают целый диапазон одним аргументом, так что пара исчезает:

std::ranges::sort(v);          // вместо sort(v.begin(), v.end())
auto n = std::ranges::count(v, 42);

Ещё больший выигрыш даёт часть библиотеки, посвящённая представлениям, которая превращает эти два ручных цикла в единый декларативный конвейер.

Продолжите этот урок на YourAIZone

В полном уроке — объяснение целиком, разобранные примеры, частые ошибки, тесты с мгновенной проверкой и ИИ-репетитор. Начните сразу как гость или создайте аккаунт, чтобы сохранять прогресс.

В полном уроке

  • Объяснение целиком
  • Разобранные примеры
  • Частые ошибки и как их избежать
  • Тестовые вопросы: 15
  • ИИ-репетитор, который отвечает на вопросы по теме
  • Отслеживание прогресса для ученика, родителей и учителя