As a C++ programmer, you're likely familiar with the traditional for loop, which allows you to iterate over a sequence of elements in a container. However, C++11 introduced a new type of for loop that offers a more concise and expressive syntax for iterating over containers: the range-based for loop. In this article, we'll explore the basics of range-based for loops in C++, and show you how to use them to iterate over arrays, vectors, maps, and other container types.
What is a Range-Based For Loop?
A range-based for loop, also known as a for-each loop, is a type of for loop that enables you to iterate over a range of elements in a container. The syntax of a range-based for loop is as follows:
for (auto element : container) {
// do something with element
}
The range-based for loop consists of three parts:
- The keyword for, followed by a pair of parentheses that enclose the loop's control variables.
- The loop control variable, which is declared using the auto keyword. This variable represents each element of the container as the loop iterates over it.
- The container, which is the range of elements that the loop will iterate over.
Compared to the traditional for loop, the range-based for loop has a simpler syntax that makes it easier to read and write code that iterates over container elements. Additionally, it is less error-prone than the traditional for loop, as it avoids issues with container bounds and index calculations.
Using Range-Based For Loops with Arrays
Let's start by looking at how to use range-based for loops with arrays. In C++, an array is a collection of elements of the same type, stored in contiguous memory locations. Here's an example of how to use a range-based for loop to iterate over an array of integers:
int arr[] = {1, 2, 3, 4, 5};
for (auto element : arr) {
std::cout << element << " ";
}
In this example, we declare an array of integers and initialize it with five elements. We then use a range-based for loop to iterate over the elements of the array, printing each element to the console.
Using Range-Based For Loops with Vectors
Vectors are one of the most commonly used container types in C++. A vector is a sequence of elements of the same type that can grow or shrink dynamically. Here's an example of how to use a range-based for loop to iterate over a vector of strings:
std::vector<std::string> vec = {"apple", "banana", "orange"};
for (auto element : vec) {
std::cout << element << " ";
}
In this example, we declare a vector of strings and initialize it with three elements. We then use a range-based for loop to iterate over the elements of the vector, printing each element to the console.
Using Range-Based For Loops with Maps
Maps are associative containers that store key-value pairs. Each key maps to a corresponding value, and keys must be unique. Here's an example of how to use a range-based for loop to iterate over a map of integers and strings:
std::map<int, std::string> mymap = {{1, "apple"}, {2, "banana"}, {3, "orange"}};
for (auto element : mymap) {
std::cout << element.first << ": " << element.second << " ";
}
In this example, we declare a map that associates integer keys with string values. We then use a range-based for loop to iterate over the key-value pairs in the map, printing each key and value to the console. Note that the loop control variable is a pair of values, where the first element is the key and the second element is the value.
Using Range-Based Loops with User-Defined Types
Range-based loops can also be used with user-defined types, such as classes or structs. However, in order to do this, we need to define the necessary operators to allow the range-based loop to work. Here's an example of how to define the necessary operators to allow a range-based loop to work with a custom class:
#include <iostream>
#include <vector>
class MyClass {
public:
MyClass(int x): _x(x) {}
int getX() const { return _x; }
private:
int _x;
};
class MyContainer {
public:
MyContainer() {
_vec.push_back(MyClass(1));
_vec.push_back(MyClass(2));
_vec.push_back(MyClass(3));
}
std::vector<MyClass>::const_iterator begin() const { return _vec.begin(); }
std::vector<MyClass>::const_iterator end() const { return _vec.end(); }
private:
std::vector<MyClass> _vec;
};
int main() {
MyContainer container;
for(auto& element: container) {
std::cout << element.getX() << " ";
}
return 0;
}
By defining the begin() and end() operators, we can now use a range-based for loop to iterate over the elements of our custom container.
Modifying Elements with Range-Based For Loops
Range-based for loops not only allow us to read container elements but also to modify them. To modify the elements in a container, we need to use a reference to the loop control variable, as shown in the following example:
std::vector<int> vec = {1, 2, 3, 4, 5};
for (auto& element : vec) {
element *= 2;
}
In this example, we declare a vector of integers and initialize it with five elements. We then use a range-based for loop to iterate over the elements of the vector and double each element by modifying it through a reference to the loop control variable. After the loop finishes, the vector will contain the elements {2, 4, 6, 8, 10}.
Using Const References with Range-Based For Loops
If we only need to read container elements and not modify them, we can use a const reference to the loop control variable. This is a good practice since it avoids accidental modifications to the container, making the code more robust. Here's an example of how to use a const reference with a range-based for loop:
std::vector<int> vec = {1, 2, 3, 4, 5};
for (const auto& element : vec) {
std::cout << element << " ";
}
In this example, we declare a vector of integers and initialize it with five elements. We then use a range-based for loop with a const reference to iterate over the elements of the vector, printing each element to the console.
Range-Based For Loops vs Traditional For Loops
While range-based for loops offer a simpler and more expressive syntax for iterating over containers, there are situations where a traditional for loop may be more appropriate. For example, if we need to iterate over a container and access its elements using an index, or if we need to iterate over a sequence of elements that are not stored in a container, a traditional for loop may be the best option. However, in most cases where we need to iterate over a container and access its elements, a range-based for loop is the preferred choice due to its simplicity and reduced potential for errors.
'프로그래밍 > C++ 문법' 카테고리의 다른 글
Type Conversions in C++ (0) | 2023.02.27 |
---|---|
Operator Overloading in C++ (0) | 2023.02.23 |
Object-Oriented Programming in C++ (0) | 2023.02.20 |
Function Pointers in C++ (0) | 2023.02.07 |
Dynamic Memory Allocation in C++ (0) | 2023.02.06 |