Skip to content
C++ Better Explained
Go back
C++ Range-Based For Loop: The Modern Way to Loop (Beginner Guide)
Edit page

C++ Range-Based For Loop: The Modern Way to Loop

Since C++11, there’s a cleaner way to walk through arrays, vectors, and strings without juggling index variables. The range-based for loop reads almost like plain English and eliminates a whole category of off-by-one bugs.


The Syntax

A range-based for loop has two parts: a variable that receives each element, and the container to loop over.

for (element_type variable : container) {
    // use variable
}

Here it is iterating over a vector:

#include <iostream>
#include <vector>

int main() {
    std::vector<int> nums = {10, 20, 30, 40};
    for (int n : nums) {
        std::cout << n << " ";
    }
    std::cout << "\n";  // prints: 10 20 30 40
    return 0;
}

No i = 0, no i < nums.size(), no nums[i]. The loop visits every element automatically, in order.


Comparing to the Traditional Loop

Here’s the same task written the old way:

for (int i = 0; i < nums.size(); i++) {
    std::cout << nums[i] << " ";
}

Both print the same thing, but the range-based version has no index to mismanage. The traditional loop is where off-by-one errors live — writing <= instead of <, or starting at 1 instead of 0. The range-based loop sidesteps all of that, which is why it’s the preferred default for simple iteration.

If you're looking to go deeper with C++, the C++ Better Explained Ebook is perfect for you — whether you're a complete beginner or looking to solidify your understanding. Just $19.

Using auto to Save Typing

Spelling out the element type gets tedious, especially for complex types. The auto keyword lets the compiler figure it out for you:

#include <iostream>
#include <map>
#include <string>

int main() {
    std::map<std::string, int> scores = {{"Alice", 90}, {"Bob", 85}};
    for (auto entry : scores) {
        std::cout << entry.first << ": " << entry.second << "\n";
    }
    return 0;
}

For maps, each element is a key-value pair, so entry.first is the key and entry.second is the value.


References: Modify in Place and Avoid Copies

By default, the loop variable is a copy of each element. To change the original elements, add & to make it a reference:

std::vector<int> nums = {1, 2, 3};
for (int& n : nums) {
    n *= 2;  // modifies the actual vector
}
// nums is now {2, 4, 6}

If you only need to read elements but want to avoid copying large objects (like strings), use const auto&:

std::vector<std::string> words = {"hello", "world"};
for (const auto& w : words) {
    std::cout << w << "\n";  // no copy, can't accidentally modify
}

This const auto& pattern is the efficient, safe default for read-only loops over containers of objects. It copies nothing and protects you from accidental edits.


The Limitations

The range-based loop trades flexibility for simplicity. You can’t get the current index, you can’t easily skip elements or step by two, and you can’t iterate in reverse without extra tools. When you need any of those, fall back to a traditional for loop. For plain “do something to every element” tasks, though, the range-based loop wins on readability every time.



Take Your C++ Further

If you’re looking to go deeper with C++, the C++ Better Explained Ebook is perfect for you — whether you’re a complete beginner or looking to solidify your understanding. Just $19.

👉 Get the C++ Better Explained Ebook — $19

📋

Free Download: The 10 Mistakes Every C++ Beginner Makes

A free 1-page checklist that shows the exact traps that slow down every C++ beginner — so you can avoid them from day one.

🔒 No spam. Unsubscribe anytime.


Edit page
Share this post on:

Previous Post
C++ Prime Number Program: Check and Print Primes for Beginners
Next Post
How to Swap Two Numbers in C++: 4 Methods Explained