9.19 — For-each loops

In lesson 6.3 -- Arrays and loops, we showed examples where we used a for loop to iterate through each element of an array.

For example:

While for loops provide a convenient and flexible way to iterate through an array, they are also easy to mess up and prone to off-by-one errors.

There’s a simpler and safer type of loop called a for-each loop (also called a range-based for-loop) for cases where we want to iterate through every element in an array (or other list-type structure).

For-each loops

The for-each statement has a syntax that looks like this:

for (element_declaration : array)

When this statement is encountered, the loop will iterate through each element in array, assigning the value of the current array element to the variable declared in element_declaration. For best results, element_declaration should have the same type as the array elements, otherwise type conversion will occur.

Let’s take a look at a simple example that uses a for-each loop to print all of the elements in an array named fibonacci:

This prints:

0 1 1 2 3 5 8 13 21 34 55 89

Let’s take a closer look at how this works. First, the for loop executes, and variable number is set to the value of the first element, which has value 0. The program executes the statement, which prints 0. Then the for loop executes again, and number is set to the value of the second element, which has value 1. The statement executes again, which prints 1. The for loop continues to iterate through each of the numbers in turn, executing the statement for each one, until there are no elements left in the array to iterate over. At that point, the loop terminates, and the program continues execution (returning 0 to the operating system).

Note that variable number is not an array index. It’s assigned the value of the array element for the current loop iteration.

For each loops and the auto keyword

Because element_declaration should have the same type as the array elements, this is an ideal case in which to use the auto keyword, and let C++ deduce the type of the array elements for us.

Here’s the above example, using auto:

For-each loops and references

In the following for-each example, our element declarations are declared by value:

This means each array element iterated over will be copied into variable element. Copying array elements can be expensive, and most of the time we really just want to refer to the original element. Fortunately, we can use references for this:

In the above example, element will be a reference to the currently iterated array element, avoiding having to make a copy. Also any changes to element will affect the array being iterated over, something not possible if element is a normal variable.

And, of course, it’s a good idea to make your reference const if you’re intending to use it in a read-only fashion:


In for-each loops element declarations, if your elements are non-fundamental types, use references or const references for performance reasons.

Rewriting the max scores example using a for-each loop

Here’s the example at the top of the lesson rewritten using a for each loop:

Note that in this example, we no longer have to manually subscript the array or get its size. We can access the array element directly through variable score. The array has to have size information. An array that decayed to a pointer cannot be used in a for-each loop.

For-each loops and non-arrays

For-each loops don’t only work with fixed arrays, they work with many kinds of list-like structures, such as vectors (e.g. std::vector), linked lists, trees, and maps. We haven’t covered any of these yet, so don’t worry if you don’t know what these are. Just remember that for each loops provide a flexible and generic way to iterate through more than just arrays.

For-each doesn’t work with pointers to an array

In order to iterate through the array, for-each needs to know how big the array is, which means knowing the array size. Because arrays that have decayed into a pointer do not know their size, for-each loops will not work with them!

Similarly, dynamic arrays won’t work with for-each loops for the same reason.

Can I get the index of the current element?

For-each loops do not provide a direct way to get the array index of the current element. This is because many of the structures that for-each loops can be used with (such as linked lists) are not directly indexable!

Since C++20, range-based for-loops can be used with an init-statement just like the init-statement in if-statements. We can use the init-statement to create a manual index counter without polluting the function in which the for-loop is placed.

The init-statement is placed right before the loop variable:

for (init-statement; element_declaration : array)

In the following code, we have two arrays which are correlated by index. For example, the student with the name at names[3] has a score of scores[3]. Whenever a student with a new high score is found, we print their name and difference in points to the previous high score.


Alex beat the previous best score of 0 by 84 points!
Betty beat the previous best score of 84 by 8 points!
The best score was 92

The int i{ 0 }; is the init-statement, it only gets executed once when the loop starts. At the end of each iteration, we increment i, similar to a normal for-loop. However, if we were to use continue inside the loop, the ++i would get skipped, leading to unexpected results. If you use continue, you need to make sure that i gets incremented before the continue is encountered.

Before C++20, the index variable i had to be declared outside of the loop, which could lead to name conflicts when we wanted to define another variable named i later in the function.


For-each loops provide a superior syntax for iterating through an array when we need to access all of the array elements in forwards sequential order. It should be preferred over the standard for loop in the cases where it can be used. To prevent making copies of each element, the element declaration should ideally be a reference.

Quiz time

This one should be easy.

Question #1

Declare a fixed array with the following names: Alex, Betty, Caroline, Dave, Emily, Fred, Greg, and Holly. Ask the user to enter a name. Use a for each loop to see if the name the user entered is in the array.

Sample output:

Enter a name: Betty
Betty was found.
Enter a name: Megatron
Megatron was not found.

Hint: Use std::string_view as your array type.

Show Solution

9.20 -- Void pointers
9.18 -- Member selection with pointers and references

359 comments to 9.19 — For-each loops

  • Józef


    I’m having issues with my code. The auto does not see that I’m using std::string. Even when I change the const auto (in for-each-loop condition) to std:string, the compiler still complains about bad referencing ‘std::string’ to ‘char’. This is the code:




    • Alex

      Your code has several issues:
      1) Your array of names is defined incorrectly.
      2) Your array of names is passed into lookForName incorrectly.

      Once you address those two issues, your program should work.

      • Matheus

        But once your array is passed into lookForName, it decays into a pointer, so it won't work either, right? Another issue is that your for-each loop will print "nameRef was not found" for every element in the list, if it's not equal that element.

  • moh.yasir

    Help me please. . .

    #include <iostream>

    const int ANGKA_RAHASIA = 11,213;
    const BESAR_GAJI = 18.35

        int satu, dua;
        double first, second;
        satu = 18;
        dua = 11;
        pertama = 25;
        kedua = pertama * three;
        kedua = 2 * ANGKA_RAHASIA;
        cout<<pertama<< " " <<kedua <<ANGKA_RAHASIA<< endl;
        jumlahGaji = jamKerja * BESAR_GAJI
        cout<<"Gaji = "<<jumlahGaji<< endl;
        return 0;

    • Alex

      This program has a lot of bugs. The only one that might be confusing is the first one: the literal value 11,213 should not have a comma. For the rest of the bugs, compile your program, look at what it's complaining about, and fix it. The rest of the issues are all very straightforward.

  • Sam

    Hi! I'm learning C++, and I feel that the auto keyword should be avoided because adding more implicit things seems like a very bad idea. I feel more comfortable when I know exactly what the variable I'm working with actually is. If I see auto, I have to go and look above until I can myself figure out what it'll be converted to by the compiler. Or, what is worse, I can make a false assumption, which would lead to undefined behaviour. It just seems more work to do when looking at the code. It might be easier to write, but a lot harder to maintain. As the python zen says "explicit is better than implicit".

  • Kılıçarslan

    Alex,I have a simple question.This code below is the one you taught.

    But there is this one I noticed.You didn't tell anything about this.I wonder why this works,or when is this implemented and why you never said anything about.Thanks in advance.

    • Alex

      I didn't mention it because I wasn't aware of it.

      It looks like Visual studio supports use of the "in" keyword instead of a colon -- it performs the same function. This is a historical artifact left over from the fact that Visual Studio supported for each loops prior to them being formally defined as part of C++11.

      Because this "in" keyword is not part of the official C++ standard and is not cross-browser compatible, its use is not recommended.

  • Kārlis

    I can not understand why is const std::string neccessary rather than using just std::string?

  • Hi Alex,
    I getting one compilation error using for-each loop

    the error is: 1>c:\users\hp1\documents\visual studio 2010\projects\cpp_basics\cpp_basics\for_each.cpp(13): error C2143: syntax error : missing ',' before ':'

    Is it because of compiler standard? I don't know how to change the compiler standard. Can you please help me to do this

    • Alex

      Sounds like your compiler may not be C++11 capable. You might try using Google to see if there's a way to turn C++11 functionality on for your specific compiler, or whether you'll need to upgrade to a newer compiler.

  • Elpidius

    Hi Alex,

    I wasn't sure whether the variable declared in the element_declaration, was initialized (and created and destroyed) every iteration; or whether it was simply initialized with the value of the first array element at the beginning and simply assigned the values of the subsequent array elemements for its relevent iteration.

    I have validated this and the latter is true:

    is the equivalent of:

    I found this out by printing the address of the element_declaration variable every iteration to see whether the address would be identical or not:

    This printed:
    array[0] has memory address 003EFCF4
    array[1] has memory address 003EFCF4
    array[2] has memory address 003EFCF4
    array[3] has memory address 003EFCF4
    array[4] has memory address 003EFCF4

    As you can see the memory address is identical.

  • Jester

    #include "stdafx.h"
    #include <iostream>
    #include <string>
    int main()
        std::string names[4] = { "Jester","Paulette","Lorreinne","Trisha" };
        std::cout << "How many times? ";
        int multiplier;
        std::cin >> multiplier;
        std::string getNames;
        bool found(false);
        for (int index = 1;index < multiplier+1;++index)
            std::cout << "Enter a name #" << index << "  ";
            std::cin >> getNames;
            for (auto &NAMES : names)
                if (NAMES == getNames)
                    found = true;

            if (found)
                std::cout << getNames << " is found.\n";
            if (!found)
                std::cout << getNames << " is not found.\n";

  • Jim

    I get confused with some of the wording in C++. When you say, an array decays into a pointer, what does that actually mean? Isn't it true that you always have a pointer,  pointing to the first element of any array?
    Another problem I have is with the words dereference a pointer.  When you dereference a pointer you are actually getting a copy of the content from the memory address the pointer points too, right?
    What happens if you have more than one pointer pointing to the same memory address?
    Can't you get the same contents for both pointers by dereferencing them both?

    • Alex

      > Isn’t it true that you always have a pointer, pointing to the first element of any array?

      No. An array is not the same thing as a pointer. An array contains type information about how long the array is, a pointer does not.

      > When you say, an array decays into a pointer, what does that actually mean?

      It means that in most circumstances, when you use an array, C++ first implicitly converts the array into a pointer (losing the size information), and then uses the pointer.

      > When you dereference a pointer you are actually getting a copy of the content from the memory address the pointer points too, right?

      Yes, you're accessing the value at the memory address the pointer points to. However, it doesn't make a copy unless you do something with that value that causes a copy to be made (e.g. assign it to another variable).

      > What happens if you have more than one pointer pointing to the same memory address?

      Exactly what you'd expect -- two pointers holding the same address. There's no problem with that.

      > Can’t you get the same contents for both pointers by dereferencing them both?


  • Sachin

    Hi Alex, Hope u are doing fine.
    I was wondering that, in the last chapters, if references were said to be implicitly constants, and that they acted like const pointers, how can they be used in for each loops where the reference element refers to a different array element each time during an iteration. I used the &reference on std::cout to print the address of the referred elements, and saw that indeed the address reference referred to was changing during each iteration. Please put some light onto it.

    • Alex

      If I understand correctly, you're asking how the for each loop is changing the value of a const reference with each iteration (since const values can typically only be initialized, not assigned new values once created)? The answer is that the element_declaration is local to the loop body, so it gets created and initialized anew with each array iteration and goes out of scope and gets destroyed at the end of each iteration.

      • Shiva


        I think Sachin is asking how a reference can be “redirected” to different array elements in different iterations. I had the same doubt. Your answer cleared it for me before asking. Thanks!

        BTW you put an extra period at the end of the "rule".

      • Shiva

        Now that I think of it, it feels pretty strange. As per your answer each iteration in a for each loop uses it’s own local reference variable which gets destroyed at the end of the iteration. The odd bit is that it's declared in the same place as a loop variable in a traditional for loop (which don’t get destroyed during each iteration), but still behaves like a variable declared in the body of a loop.

        • Alex

          Yup. The syntax for the for-each loop obscures the nature of when and where the reference is created, destroyed, and initialized. From a usage standpoint, it really doesn't matter. It's only when you start digging into how these things actually work that you start to uncover oddnesses.

          • Shiva

            Which is exactly what an astute student should do! :D

            Thanks a lot for the quick and continued responses. Readers like me are benefiting a lot. :)

  • Rob G.

    Hi Alex, I'm getting 0-->51 in readback instead of 1-52. How do I fix this? Should I revert to traditional loops for the remainder of the exercises (almost at blackjack exercise)?

    • Alex

      It's not a good idea to mix a for-each loop with explicit indexing like you're doing in populate_array(). If you need to access specific indices, use traditional loops.

    • Shiva

      Hi Rob,

      May I help you? Inside populate_array(), use:

      instead. This works. Here element is a reference to the actual array element, so modifying it modifies the array itself. You don't need to access the members with indices.

      Keep coding. :)

  • carr002

    "C++11 introduces a new type of loop called a for-each loop (also called a range-based for loop)"

    Note - don't confuse this with the for_each(..) STL function in <algorithm>. If using a range-based for loop then call it a range-based for loop and not a for-each loop as that could cause confusion.

  • Bede

    Hi Alex,
    in the sentence "Can I get the index of an the current element?" the "an" can be removed.

  • Lokesh

    In the first example the comment on line 7 should be
    "// keep track of our largest score"
    instead of
    "// keep track of index of our largest score"
    Alternatively you can change the code if you want.

  • Satwant

    For-each loops and references

    In the for-each examples above, our element declarations are declared by value:

        int array[5] = { 9, 7, 5, 3, 1 };
        for (auto element: array) // element will be a copy of the current array element
            std::cout << element << ' ';
    This means each array element iterated over will be copied into variable element. Copying array elements can be expensive, and (((*most of the time we really just to reference the original element.*))) Fortunately, we can use references for this:

    Type problem: most of the time we really just want to refer the original element.

  • Joseph

    Under section "For-each doesn’t work with pointers to an array", I believe

    should instead be

  • Rob G.

    Alex, I misunderstood the objective: I'm sorry I thought we were to continue the loop ad infinitum until the name was found.
    I've got a traditional control loop nesting a for-each.

    My question: are we supposed to experience any actual change in output of this program using the reference to original storage address(&)& vs. not? Or, are we just supposed to know it will reduce overhead if used? Also what are the liabilities of leaving const out?

    • Alex

      > are we supposed to experience any actual change in output of this program using the reference to original storage address(&)& vs. not? Or, are we just supposed to know it will reduce overhead if used?

      No change in output, just an increase in efficiency.

      > Also what are the liabilities of leaving const out?

      In this case, not much. Const in this case is used primarily to ensure we don't change something we didn't intend to change.

  • Rob G.

    Hi Alex, are we to assume that the for-each loop can have only one statement or am I doing something incorrectly?

    • Alex

      Loops can only have one statement.

      However, you can easily work around this by using blocks:

  • For the sake of a good example, it might be a good idea to use this foreach code in the Quiz solution:

  • OmniTroid

    Is there a reason why you chose to not let 'score' be a reference in your rewriting of the max score program?
    As in this:

    As opposed to the (supposedly more efficient as covered just before in the lesson):

    Loving your lessons, by the way. They are very easy to follow and explains underlying concepts very well. I'll make sure to recommend them to anyone who wants to look into c++!

  • Annibale

    I tried to modify your program to detect the maximum score by asking the user to insert the number n of scores and then letting the machine to generate n random numbers. The program should print all the random generated scores and the maximum. If I declare

    everything works great. If I declare

    I get a bunch of problems. Here is the code. Could you explain me why? Thanks a lot for your help!

    • Alex

      For-each loops won't work with dynamically allocated arrays, because dynamically allocated arrays don't know how large they are. Fixed arrays don't have this problem (unless they decay to a pointer).

      If you want to use the built-in dynamic arrays, you'll need to iterate with a standard for loop. If you want to use the for-each loops, you'll have to use fixed arrays (or even better, std::array) or std::vector (which we cover in a few lessons).

  • Te KA

    in example in section "For-each loops and non-arrays", add

  • cesare

    Hi Alex, I have a question for you that doesn't refer to quiz in this chapter (it was easy as you also said).
    While doing your quizzes I sometimes look at the c++ documentation on, usually about 'cin' and 'string' and to add some errors checking in my quizzes solutions. But reading all that stuff is incredibly hard for me and I end up understanding only few example code.
    I've spent last 2 years learning and writing tons of objective-c code (actually without creating nothing very interesting, just for the fun of learning), and I know how important is to be able to read official Apple documentation.
    My question is: do you think I will be able to consult documentation at at the end of all these tutorial?



    • Alex

      I think it will be easier for you to do so, as you'll have more C++ concepts under your belt. That said, the technical documentation can still be quite hard to interpret -- even I struggle to follow sometimes. So I don't think it will be easy -- just easier than it is now.

  • Gopal

    A question Alex:

    for (auto &element: array)

    Since we are just referencing the variable "element" to original array element but not actually copying the value of original element to variable "element", how can you print the valve of "element" variable to console while it don't have the valve at all?

    std::cout << element << ' ';    ???????????????

    • Alex

      Element is just an alias for array[i], where i is the current index number. Element doesn't need a copy of the original variable because it is a reference to the original variable.

      It's like if I gave you the name "Joe". I'm not making a copy of you, I'm just giving you another name. You're still the original Gopal, but I can now also refer to you by the name "Joe".

      • Gopal

        for (auto &element: array)

        As per my understanding after reading some next lessons, in above statement &element holds address of array[i], where i is the current index number. so if we want to print value which &element is pointed to, we should dereference it. In this case we should write   std::cout << *&element << ‘ ‘;. Pl. clarify.

        • Alex

          Aah yes, this is a common confusion amongst new programmers. In the context of a variable declaration, the & doesn't mean address-of, it means reference-to. We talk about references (and revisit this example) in lesson 6.11 -- References. Perhaps I should move this lesson until after we've covered references.

          • Gopal

            Got it Alex Thanks.

            I spent 1/2 hour to find this comment on Friday and 1/2 hour on Monday in earlier chapters. Today i found this comment here. I don't know how this comment came here, perhaps you moved entire chapter here. It was really irritating to find comment i posted. Anyway finally i got this comment and more importantly i understood difference between address-of and reference-to.

            • Alex

              I moved the whole lesson. Lots of people were getting confused about the references stuff since I hadn't introduced references yet. This way, the reference lessons come first.

          • Gopal

            One suggestion:

            I think For-each loops section should not be in this chapter. Instead it should belongs to chapter 5 control flow only.

            Apart from that "For-each loops and references" section should not be here. It should belongs to 6.11 reference variable section.

            If you want to keep "For-each loops and references" in this section, then you should provide link to section 6.11 reference variable section (If you decide to move this section in chapter 5).

            • Alex

              Thanks for the thought.

              It's kind of an odd-ball lesson. It doesn't make sense to put it in chapter 5 because although it is a control flow topic, it needs a sequence of data to operate on, and we don't introduce any of those until the beginning of chapter 6 (arrays).

              I do like how arrays and references are discussed before they're used in this lesson now. That avoid confusion and splitting the topic over multiple lessons.

  • msk

    There is a syntax error : missing ',' before ':'

    even tried copy pasting from this page

    • Alex

      No, the example is correct. My guess is that your compiler is either not C++11 capable, or has that capability turned off (if you're using Code::Blocks, go to Toolbar -> Settings -> Compiler, select the "Compiler settings" tab and the "compiler flags" tab, and make sure the checkbox "Have g++ follow the C++11 ISO C++ language standard [-std=c++11]" is checked).

  • Len

    Hi Alex,
    For some reason I cannot get the code to compile when it is in a function, but it works fine when it is in "main".  I am really stuck on this.  What is wrong with this code?

    • Devashish

      Hello Len, May I help you?
      The problem with simple fixed length arrays is that when passed to a function, they break into pointers. I guess you have defined the array in your main(). When main passes the array to function printArray(), it decays into a pointer that points to that array. Thus, the variable a, that you declared as printArray's parameter, never receives the actual array. It just holds the address of the array that you have passed in. for each loop prints the elements in the array only if it's size is known. Because value of a is not your array, compiler throws an error where you tried to print elements using for each loop. A simple solution is to use std::array (covered in 6.15) or std::vector (covered in 6.16) instead of simple arrays. Arrays defined using these methods doesn't decay into pointers. They remain arrays even if passed to a function.

      • Len

        I suspected that Alex was not passing arrays yet because he had not covered the "trick" in how to do this.. yet.

        Thanks for sharing the "trick", Devashish!  When I get to those sections I will play around with it more.

    • Elpidius

      Hi Len,

      It is possible to pass the address of the array as a parameter. Once this pointer is dereferenced it is possible to iterate this array (dereferenced pointer) inside a function using a for-each loop.

      Consider the following:

      This prints:
      9 7 5 3 1

      This works because 'ptr' in printArray() is pointing to the array itself, and not the first element of the array (which would be the case if the argument passed to printArray() was 'array').

  • Mosleh

    Hi Alex,
    Could I use goto statement for this problem. Does it harmful for this kind of situation. Although I learn it from your lesson 5.4

  • eli


    Does the "for each" loop provide also the index of the element we are dealing now with?
    (Of course, you can calculate it manually, but it's a little annoying to add such variable and increment it)
    It's useful when the index has a meaning (e.g. the example in 6.2 - arrays and enums)


    • Alex

      The for each loop does not provide an index, because it can be used with aggregates that don't support indexing (e.g. trees or linked lists).

  • Raj

    Hello Alex,

    Thanks for the tutorials :)
    Using the for each loops how can we find the index of a member in the array. i.e., How can we find the index of the largest value in the array.

    • Alex

      When using a for each loop, there's no direct way to get the index. This is intentional, as for each loops can be used with other (non-array) kinds of data structures (like trees or linked lists) that don't support direct indexing.

      If you need the index, you're best off using a normal for loop.

      It occurs to me that if you know you're looping over an array, you could use a reference loop variable (to ensure the loop variable represents the actual array element and not a copy) and some pointer arithmetic:

  • ashis

    hello alex,

    #include <iostream>

    int main()
        using namespace std;
        string str[]={"alex","betty","cameron","james","broad","finn"};
        string item;
        int count=0;
        int flag=0;
        cout<<"enter a string"<<endl;
        for(string name:str)

         cout<<item <<"is found"<< "at position" <<count<<endl;
        cout<<item <<"is not found"<<endl;

    return 0;

    when i run this code,it works fine.
    but when i provide the string input as ("james"  for example),it gives the output :james is not found.
    where as the string is already present in the array.
    could you please clarify on this!!

    • Alex

      Your code almost works, but it has a simple logic error that's causing the loop to terminate earlier than expected. This is the perfect kind of problem to use a debugger to find! Place a breakpoint on the if statement, and watch what happens when it compares "james" and "alex".

    • Bogdan

      On the else branch you don't need the break, that causes the problem. The for loop exists early when the first name mismatches not having the chance to go to the next names.

Leave a Comment

Put all code inside code tags: [code]your code here[/code]