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

Цикл 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}
