Results 1 to 11 of 11

Thread: Iterators in C++

  1. #1
    Join Date
    Dec 2011
    Location
    Toronto, Ontario
    Posts
    6,424
    Mentioned
    84 Post(s)
    Quoted
    863 Post(s)

    Default Iterators in C++

    Can someone give me a crash course on them? I just learned about vectors, and iterators are sorta confusing me :/
    @Brandon

  2. #2
    Join Date
    Feb 2011
    Location
    The Future.
    Posts
    5,600
    Mentioned
    396 Post(s)
    Quoted
    1598 Post(s)

    Default

    Quote Originally Posted by Sin View Post
    Can someone give me a crash course on them? I just learned about vectors, and iterators are sorta confusing me :/
    @Brandon

    Iterators? They work the same way as pointers. Think of them the same as in Java.

    In the iterator world, begin = 0 Container[0]. end = Container.size() - 1.


    C++ Code:
    vector<int> Array = {10, 11, 9};

    //Our list now looks like:

    10, 11, 9.


    for (size_t I = 0; I < Array.size(); ++I)
    {
        cout<<Array[I]; //will print 10, 11, 9.
    }

    for (size_t I = Array.size(); I > 0; --I)
    {
        cout<<Array[I];  //will then print 9, 11, 10.
    }


    //Similarly, the following uses iterators to do the same:

    for (vector<int>::iterator I = Array.begin(); I != Array.end(); ++I)
    {
        //Prints 10, 11, 9.
        cout<<*I;  //I said an Iterator was like a pointer. To get the value of the iterator, we do *IteratorVariable. The * operator de-references a pointer to get the value the pointer points at.
    }

    //vector<int>::iterator I.  This tells the compiler to create an iterator that will loop through a vector of integers.
    //I = Arrays.begin();  This tells the compiler that the iterator will start at the beginning of the array.
    //I != Arrays.end();  The loop will continue as long as the Iterator does not reach the end of the array.
    //++I.               Increment the iterator. When the Iterator reaches Arrays.end(), it will break out of the loop.



    for (vector<int>::iterator it = Arrays.end(); I != Arrays.begin(); ++I) //Loop backwards from the end to the beginning of the array.
    {
        cout<<*it;  //prints 9, 11, 10.
    }


    //Now there are other cases where dereferencing requires the pointed-by operator aka  ->  OR *.  ;
    //Example:


    pair<int, string>  Dictionary;
    Dictionary.insert(1, "Sin");
    Dictionary.insert(2, "Is");
    Dictionary.insert(3, "Learning");
    Dictionary.insert(4, "C++");


    //To iterate this, we do  pair<int, string>::iterator it = ....
    //That tells the compiler create an iterator for generic/template pair class that has the parameters <int, string>.

    //Imagine the pair class to look like the following:

    class pair<T>
    {
        T first;
        T second;
    };


    for (pair<int, string>::iterator it = Dictionary.begin(); it != Dictionary.end(); ++it) //Loop through from beginning to end..
    {
        cout<<"First Value at :"<< it->first <<" Is :"<< it->second;
    }

    //The above forloop will thus print:

    "First Value at: 1 Is: Sin"
    "First Value at: 2 Is: Is"
    "First Value at: 3 Is: Learning"
    "First Value at: 4 Is: C++"

    //The -> operator of the iterator calls the variable or function that is pointed to by the iterator. So in other words, that pair class contained a variable called first and another called second.
    //To access these variables, we do  ->first  or  -> second.
    //Another way is to do:    *it.first   or   *it.second.   //This dereferences it and then accesses the variables first, second.


    To visualize how iterators work under the hood, here's a small sample:

    C++ Code:
    vector<int> SomeList = {1, 7, 4, 2, 6, 3, 5};

    //With a pointer:

    int* iterator_begin = &SomeList[0];   //A pointer to the beginning of the List aka index [0].
    int* iterator_end = &SomeList[6];     //Our List is of size 7. Thus the last index is [6].

    //prints the entire List from beginning to end. Since iterators are pointers under the hood,
    //We must dereference the pointer to get the value.
    for (iterator_begin; iterator_begin != iterator_end; ++iterator_begin)
    {
        cout<< *iterator_begin;
       
    }

    //Notice that the above iterators are of integer type. That's because we are iterating over an integer vector.
    //A char iterator would give use bytes instead of the values in our list. That's how it all works under the hood.
    Last edited by Brandon; 05-07-2013 at 02:05 AM.

  3. #3
    Join Date
    Feb 2013
    Posts
    465
    Mentioned
    6 Post(s)
    Quoted
    221 Post(s)

    Default

    Be careful, if its the same as C then i++ and ++i are not the same statement, and have slightly different effects in loop structures.

  4. #4
    Join Date
    Feb 2011
    Location
    The Future.
    Posts
    5,600
    Mentioned
    396 Post(s)
    Quoted
    1598 Post(s)

    Default

    Quote Originally Posted by wthomas View Post
    Be careful, if its the same as C then i++ and ++i are not the same statement, and have slightly different effects in loop structures.
    Not only in C, but in every language. Though, in a for loop declaration, they have the same effect because the incrementation always happens at the end of the loop. In fact, small micro-optimization: ++I in a for-loop is faster than I++ as there is no temporary made:


    C++ Code:
    class Values<T>
    {      
        public:
            T Value = 0;
             
                    //++I Pre-Increment.
            T operator++()  //Should return T& but just for visualization, return T.
            {
                return (Value = Value + 1); //Increments the Value regardless..
            }

                    //I++  Post-Increment.
            T operator++ (T Value)  //Should return T& but just for visualization, return T.
            {
                T Temporary = Value;   //First store the original variable.
                Value = Value + 1;     //Increment the original variable.
                return Temporary;      //Return the stored value.
            }
    };
    Last edited by Brandon; 05-07-2013 at 02:29 AM.

  5. #5
    Join Date
    Feb 2013
    Posts
    465
    Mentioned
    6 Post(s)
    Quoted
    221 Post(s)

    Default

    Quote Originally Posted by Brandon View Post
    Not only in C, but in every language. Though, in a for loop declaration, they have the same effect because the incrementation always happens at the end of the loop. In fact, small micro-optimization: ++I in a for-loop is faster than I++ as there is no temporary made
    You sir are correct, just tested with java and c. There was some reason for needing one type over the other we covered a few weeks ago, using polling loops and hardware interrupts.

    I believe its mainly come from functional programming where everything is a function so :

    Code:
    i=10;
    a=10++;
    
    i=10;
    b=++10;
    Where a is 10 and b is 11. I think that is the correct way around.
    Last edited by wthomas; 05-07-2013 at 02:26 AM.

  6. #6
    Join Date
    May 2013
    Posts
    15
    Mentioned
    0 Post(s)
    Quoted
    4 Post(s)

    Default

    Quote Originally Posted by Brandon View Post
    Not only in C, but in every language. Though, in a for loop declaration, they have the same effect because the incrementation always happens at the end of the loop. In fact, small micro-optimization: ++I in a for-loop is faster than I++ as there is no temporary made:


    C++ Code:
    class Values<T>
    {      
        public:
            T Value = 0;
             
                    //++I Pre-Increment.
            T operator++()  //Should return T& but just for visualization, return T.
            {
                return (Value = Value + 1); //Increments the Value regardless..
            }

                    //I++  Post-Increment.
            T operator++ (T Value)  //Should return T& but just for visualization, return T.
            {
                T Temporary = Value;   //First store the original variable.
                Value = Value + 1;     //Increment the original variable.
                return Temporary;      //Return the stored value.
            }
    };
    Most compilers can optimize post-increment to pre-increment too.


    Quote Originally Posted by wthomas View Post
    You sir are correct, just tested with java and c. There was some reason for needing one type over the other we covered a few weeks ago, using polling loops and hardware interrupts.

    I believe its mainly come from functional programming where everything is a function so :

    Code:
    i=10;
    a=10++;
    
    i=10;
    b=++10;
    Where a is 10 and b is 11. I think that is the correct way around.
    That doesn't really make sense? How does functional programming have anything to do with that?

  7. #7
    Join Date
    Oct 2006
    Location
    ithurtsithurtsithurtsithurts
    Posts
    2,930
    Mentioned
    7 Post(s)
    Quoted
    135 Post(s)

    Default

    Quote Originally Posted by wthomas View Post
    Where a is 10 and b is 11. I think that is the correct way around.
    Yeah, you got it the right way around.

  8. #8
    Join Date
    Feb 2013
    Posts
    465
    Mentioned
    6 Post(s)
    Quoted
    221 Post(s)

    Default

    heron_ The only difference in using them is for functional programming. If you are using them for just iterating variables in loops then it matters not which you use. However in some cases you need to be specific. In non functional programming it makes no difference.

  9. #9
    Join Date
    Dec 2007
    Location
    192.168.1.73
    Posts
    2,439
    Mentioned
    6 Post(s)
    Quoted
    119 Post(s)

    Default

    Quote Originally Posted by wthomas View Post
    You sir are correct, just tested with java and c. There was some reason for needing one type over the other we covered a few weeks ago, using polling loops and hardware interrupts.

    I believe its mainly come from functional programming where everything is a function so :

    Code:
    i=10;
    a=10++;
    
    i=10;
    b=++10;
    Where a is 10 and b is 11. I think that is the correct way around.
    Java has post-incrementation?! I've been using it for years and never knew that...

  10. #10
    Join Date
    May 2013
    Posts
    15
    Mentioned
    0 Post(s)
    Quoted
    4 Post(s)

    Default

    Quote Originally Posted by wthomas View Post
    heron_ The only difference in using them is for functional programming. If you are using them for just iterating variables in loops then it matters not which you use. However in some cases you need to be specific. In non functional programming it makes no difference.
    Ok then, what about

    Code:
    buffer[i++] = x;
    vs

    Code:
    buffer[++i] = x;
    ?

    It's not "functional programming" and there's a huge difference.

  11. #11
    Join Date
    Jul 2012
    Posts
    437
    Mentioned
    10 Post(s)
    Quoted
    165 Post(s)

    Default

    Quote Originally Posted by Carll View Post
    There are two types of iterators : Pre and post.
    Pre ++i ( first increases and than use the value)
    Post i++ (first uses and than increases the value)
    Not necessarily iterators are just how you navigate between variables.
    ie: binary trees often use left(), right() and parent()

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •