Ежедневный бит (e) C++ # 136, индексированное представление C++ 23: std::views::enumerate.
Range-for-loop — это очень удобная замена цикла for в стиле C.
Однако диапазон для цикла может быть громоздким при доступе к исходному индексу или вычислении целевого индекса.
C++23 std::views::enumerate устраняет эту проблему, создавая диапазон кортежей, где i-й кортеж состоит из значения i и ссылку на i-й элемент исходного диапазона.
#include <vector> #include <ranges> std::vector<int> data{1, 2, 3, 4, 5, 6, 7}; // Applying enumerate before other views to inject original indexes constexpr auto before = std::views::enumerate | std::views::filter([](auto t) { return std::get<1>(t) % 2 == 0; }); for (auto [idx, value] : data | before) { // Iterate over: {1,2}, {3,4}, {5,6} } // Applying enumerate after other views to index the resuling range constexpr auto after = std::views::filter([](int v) { return v % 2 == 0; }) | std::views::enumerate; for (auto [idx, value] : data | after) { // Iterate over: {0,2}, {1,4}, {2,6} } // Since the second element of the tuple is a reference, // we maintain mutability for (auto [idx, value] : data | std::views::enumerate) { value -= idx; } // data == {1,1,1,1,1,1,1}
Откройте пример в Compiler Explorer.