Range-based for loop – это упрощённый цикл
for, который позволяет перебирать элементы контейнера (std::vector, std::array, std::map, std::set и т. д.) без индексов и итераторов. for (auto element : container) {
// Действие с element
}🚩Как это работает внутри?
Простой пример с
std::vector #include <iostream>
#include <vector>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
for (int x : v) { // Перебираем все элементы вектора
std::cout << x << " ";
}
}
Вывод
1 2 3 4 5
Как работает этот цикл?
Компилятор превращает его в обычный
for с итератором: for (auto it = v.begin(); it != v.end(); ++it) {
int x = *it; // Копируем элемент
std::cout << x << " ";
}🚩Передача по ссылке (`&`) и по значению (`=`)
Передача по значению (
=) – создаёт копию элементаfor (int x : v) { // x - копия элемента
x = 100; // НЕ изменит вектор!
}Передача по ссылке (
&) – изменяет оригиналfor (int& x : v) { // x - ссылка на элемент
x *= 2; // Изменит оригинальный вектор!
}🚩Работает со всеми контейнерами STL
С
std::mapstd::map<int, std::string> m = {{1, "one"}, {2, "two"}};
for (const auto& [key, value] : m) { // structured binding (C++17)
std::cout << key << " -> " << value << "\n";
}С
std::setstd::set<int> s = {1, 2, 3, 4};
for (int x : s) { std::cout << x << " "; }🚩Работает с `std::initializer_list`
for (int x : {10, 20, 30}) {
std::cout << x << " ";
}Вывод
10 20 30
🚩Как работает range-based for с обычными массивами?
int arr[] = {1, 2, 3};
for (int x : arr) { std::cout << x << " "; }Работает так же, как и с `std::vector`!
Работает с пользовательскими классами (если есть
begin() и end()) class MyContainer {
int data[3] = {10, 20, 30};
public:
int* begin() { return data; }
int* end() { return data + 3; }
};
int main() {
MyContainer c;
for (int x : c) { std::cout << x << " "; }
}Ставь 👍 и забирай 📚 Базу знаний