Ошибиться в for — циклах довольно просто. К счастью, в C++ появляется все больше и больше вариантов, исключающих ошибки.
В этой статье разберем современные подходы к итерациям в C++: от классических циклов до range-based for, std::span и алгоритмов из <ranges>.
1. Проблемы классических циклов
Классический for дает полный контроль, но легко допустит ошибку в инициализации, условиях или шаге.
for (int i = 0; i <= arr.size(); ++i) { // ошибка: выход за границы
sum += arr[i];
}2. Range-based for
C++11 ввел range-based for, который безопаснее и читается проще.
for (const auto& item : arr) {
sum += item;
}3. Безопасные диапазоны
std::span (C++20) позволяет явно передавать диапазоны без копирования данных.
void print(std::span<const int> data) {
for (int v : data) {
std::cout << v << ' ';
}
}4. Алгоритмы из <ranges>
Диапазоны помогают описывать намерение ближе к данным, а не к счетчику цикла.
auto positives = values
| std::views::filter([](int v) { return v > 0; })
| std::views::transform([](int v) { return v * 2; });5. Практический пример
Когда логика обхода становится сложнее, лучше вынести ее в отдельный диапазон или алгоритм, оставив цикл максимально прямолинейным.
6. Заключение
Используйте индексные циклы только там, где индекс действительно является частью задачи. В остальных случаях диапазоны делают код короче, понятнее и надежнее.