Daily bit(e) C++. std::views::enumerate

Добавлено 5 октября 2026 в 14:52

Daily bit(e) C++ 136, индексированное представление из C++23 – std::views::enumerate.

Daily bit(e) C++

Цикл for на основе диапазонов – очень удобная замена циклу for в стиле C.

Однако такой цикл может быть неудобен, когда требуется получить доступ к исходному индексу или вычислить целевой индекс.

Появление std::views::enumerate в стандарте C++23 решает эту проблему: этот инструмент создает диапазон кортежей, где i-й кортеж состоит из значения i и ссылки на i-й элемент исходного диапазона.

#include <vector>
#include <ranges>
#include <iostream>


std::vector<int> data{1, 2, 3, 4, 5, 6, 7};

// Применение enumerate перед другими представлениями
// для внедрения исходных индексов
constexpr auto before = std::views::enumerate | 
    std::views::filter([](auto t) {
        return std::get<1>(t) % 2 == 0;
    });
for (auto [idx, value] : data | before) 
{
    // Итерация по {1,2}, {3,4}, {5,6}
    std::cout << idx << " -> " << value << "\n";
}

// Применение enumerate после других представлений
// для индексации результирующего диапазона
constexpr auto after = std::views::filter([](int v) { 
    return v % 2 == 0;
}) | std::views::enumerate;
for (auto [idx, value] : data | after) 
{
    // Итерация по {0,2}, {1,4}, {2,6}
    std::cout << idx << " -> " << value << "\n";
}

// Поскольку второй элемент кортежа является ссылкой,
// мы сохраняем возможность изменения.
for (auto [idx, value] : data | std::views::enumerate) {
    value -= idx;
}
// data == {1,1,1,1,1,1,1}

Пример на Compiler Explorer

Теги

C++ / CppDaily bit(e) C++Программирование