Range-based for loops, introduced in C++11, provide a convenient syntax for iterating over elements of a range, such as arrays, containers, or other sequences. They offer a more concise and readable alternative to traditional for loops, especially when working with containers that support iterators.
for (range_declaration : range_expression) {
// Code to be executed for each element in the range
}
int
for an integer array).
#include
int main() {
int numbers[] = {1, 2, 3, 4, 5};
// Range-based for loop
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
// output //
1 2 3 4 5
numbers
array.num
) is assigned the value of the corresponding array element.
#include
#include
int main() {
std::vector names = {"Alice", "Bob", "Charlie"};
// Range-based for loop
for (const std::string& name : names) {
std::cout << name << " ";
}
std::cout << std::endl;
return 0;
}
// output //
Alice Bob Charlie
names
vector of strings.const std::string&
part in range_declaration
ensures we get a read-only reference to each element, preventing accidental modification within the loop.If you need to modify elements within the loop, you can either:
range_declaration
(e.g., int& num
). This allows modification, but be cautious to avoid unintended side effects.
#include
#include
int main() {
std::vector numbers = {1, 2, 3, 4, 5};
// Loop with modification
for (int& num : numbers) {
num *= 2; // Double each element
}
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
// output //
2 4 6 8 10
std::copy
Function: Use std::copy
to create a modified copy of the container within the loop, avoiding potential issues with modifying the original during iteration.
#include
#include
int main() {
std::vector numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// Iterating over a subrange of the vector (from index 2 to 5)
for (auto it = numbers.begin() + 2; it != numbers.begin() + 6; ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
return 0;
}
// Output //
3 4 5 6
Explanation: In this example, we use iterators to specify the range we want to iterate over. By using numbers.begin() + 2
and numbers.begin() + 6
, we define a subrange starting from the third element (index 2) up to the seventh element (index 5) of the vector numbers
.
#include
int main() {
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// Iterating over a subset of the array (from index 3 to 7)
for (int i = 3; i <= 7; ++i) {
std::cout << arr[i] << " ";
}
std::cout << std::endl;
return 0;
}
// Output //
4 5 6 7 8
Explanation: In this example, we use a traditional for loop with indices to specify the range we want to iterate over. By starting from index 3 and ending at index 7 (inclusive), we define a subset of elements within the array arr
to iterate over.
You can nest range-based for loops to iterate over elements in multi-dimensional containers like 2D arrays or nested containers:
#include
#include
int main() {
std::vector> matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// Nested range-based for loops to iterate over each element in the matrix
for (auto& row : matrix) {
for (auto& element : row) {
std::cout << element << " ";
}
std::cout << std::endl;
}
return 0;
}
// Output //
1 2 3
4 5 6
7 8 9
matrix
representing a 3×3 matrix.row
represents a reference to the current row.element
represents a reference to the current element.The basic syntax for iterating over key-value pairs in maps using a range-based for loop is:
for (const auto& pair : map) {
// Access pair.first for the key and pair.second for the value
}
map
is the map container.pair
is a reference to each key-value pair in the map.pair.first
accesses the key, and pair.second
accesses the corresponding value.Let’s consider an example where we have a std::map
storing the ages of individuals, where the name of the individual serves as the key and their age serves as the value. We’ll iterate over the key-value pairs to print each name and age.
#include
#include
// output //
Alice: 30
Bob: 25
Charlie: 35
std::map
named ages
that stores the ages of individuals as key-value pairs, where the name is the key and the age is the value.pair.first
to retrieve the name (key) and pair.second
to retrieve the age (value) of each individual.It’s possible to modify the values stored in the map while iterating over key-value pairs. However, care must be taken to avoid invalidating iterators, especially when modifying the keys.
Let’s consider an example where we increment the age of each individual by 1 while iterating over the map.
#include
#include
// output //
Alice: 31
Bob: 26
Charlie: 36
ages
map using a range-based for loop.pair.second++
to increment each age by 1.By default, range-based for loops provide a const reference to the element, preventing accidental modifications. If you need to modify elements, use a non-const reference as mentioned earlier.
Range-based for loops are a valuable addition to the C++ programmer's toolkit. They enhance code readability, maintainability, and type safety by providing a concise way to iterate over containers. Understanding their syntax, advanced features, and limitations will help you leverage them effectively in your C++ programs. Happy coding !❤️