Different types of range-based for loop iterators in C++

Range-Based ‘for’ loops have been included in the language since C++11. It automatically iterates (loops) over the iterable (container). This is very efficient when used with the standard library container (as will be used in this article) as there will be no wrong access to memory outside the scope of the iterable. The loop will automatically start and end at the right place.

Syntax :

for ( range_declaration : range_expression ) 
    loop_statement
    There are three different types of range-based ‘for’ loops iterators, which are:

  1. Normal Iterators:
    In normal iterator an ordinary temporary variable is diclare as the iterator, and the iterator gets a copy of the current loop item by value. Any changes made to the temporary copy will not get reflected in the original iterable.

    Syntax :



    for (datatype iterator : list)
    {
      // operation are performed here 
    }
    
    • The iterator used is a normal iterator of any data type like int, float, double, etc, which is used to iterate over any type of container.
    • list can be any type of container.

    Here is the implementation of the normal range based iterators :

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    // C++ program to implements
    // normal iterators
      
    #include <iostream>
    #include <vector>
    using namespace std;
      
    // Function to implements
    // normal iterators
    void normal_iterator(vector<int> my_iterable)
    {
      
        // Printing the iterable before making
        // any changes
        cout << "Value before modification: ";
        for (int my_iterator : my_iterable) {
            cout << my_iterator << " ";
        }
      
        // Case where the iterator
        // makes a temporary copy
        // of the current loop item
        for (int my_iterator : my_iterable) {
            // changing the value of the iterator
            my_iterator += 1;
        }
      
        cout << "\nValue after modification : ";
      
        // Printing the iterable
        // to see if any changes
        // has been made in the
        // original container or not
        for (int my_iterator : my_iterable) {
            cout << my_iterator << " ";
        }
    }
    // Driver Code
    int main()
    {
        // Initialising a standard
        // template container
        vector<int> my_iterable;
        my_iterable.push_back(101);
        my_iterable.push_back(102);
        my_iterable.push_back(103);
        my_iterable.push_back(104);
      
        normal_iterator(my_iterable);
      
        return 0;
    }

    chevron_right

    
    

    Output:

    Value before modification: 101 102 103 104 
    Value after modification : 101 102 103 104
    
  2. Reference Iterators :
    Reference iterators are declared as a reference variable, and the iterator gets the value of the current item by reference. So the changes made inside the loop are definitely get affected in the original container itself.

    Syntax :

    for (datatype & iterator : list)
    {
      // operation are performed here 
    }
    
    • The iterator used is a normal iterator of any data type like int, float, double, etc, which is used to iterate over any type of container.
    • list can be any type of container.

    Here is the implementation of the normal range based iterators :

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    // C++ program to implements
    // reference iterators
      
    #include <iostream>
    #include <vector>
    using namespace std;
      
    // Function to implements
    // reference iterators
    void reference_iterator(vector<int> my_iterable)
    {
      
        // Printing the iterable before
        // making any changes
        cout << "Value before modification: ";
        for (int my_iterator : my_iterable) {
            cout << my_iterator << " ";
        }
      
        // Iterating the container
        // using reference iterator
        // and updating the value
        for (int& my_iterator : my_iterable) {
      
            my_iterator += 1;
        }
      
        cout << "\nValue after modification : ";
        for (int my_iterator : my_iterable) {
            cout << my_iterator << " ";
        }
    }
      
    // Driver Code
    int main()
    {
        // Initialising a standard
        // template container
        vector<int> my_iterable;
        my_iterable.push_back(101);
        my_iterable.push_back(102);
        my_iterable.push_back(103);
        my_iterable.push_back(104);
      
        reference_iterator(my_iterable);
      
        return 0;
    }

    chevron_right

    
    

    Output:

    Value before modification: 101 102 103 104 
    Value after modification : 102 103 104 105
    
  3. Constant Iterators :
    Constant iterators are declared as a reference to a constant and in this case, no copy of the current loop item will be made making the execution faster as compared to the above two cases. This is useful in cases where we don’t want any accidental changes in the iterator value or if we are iterating over large items in a container. If we will try to modify the existing value then the compiler will show errors.

    Syntax :

    for (const datatype iterator : list)
    {
      // operation are performed here 
    }
    
    • The iterator used is a normal iterator of any data type like int, float, double, etc, which is used to iterate over any type of container.
    • list can be any type of container.

    Here is the implementation of the normal range based iterators :

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    // C++ program to implements
    // constant iterators
      
    #include <iostream>
    #include <vector>
    using namespace std;
      
    // Function to implements
    // constant iterators
    void reference_iterator(vector<int> my_iterable)
    {
      
        // Printing the iterable
        // using constant iterator
        for (const int& my_iterator : my_iterable) {
      
            cout << my_iterator << " ";
      
            // Uncomment below line to see the error
            // my_iterator += 1 ;
        }
    }
      
    // Driver Code
    int main()
    {
        // Initialising a standard
        // template container
        vector<int> my_iterable;
        my_iterable.push_back(101);
        my_iterable.push_back(102);
        my_iterable.push_back(103);
        my_iterable.push_back(104);
      
        reference_iterator(my_iterable);
      
        return 0;
    }

    chevron_right

    
    

    Output:

    101 102 103 104
    

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.