Thread: help w/template iters

  1. #1
    Registered Abuser
    Join Date
    Sep 2007
    Location
    USA/NJ/TRENTON
    Posts
    127

    help w/template iters

    ok this is an abridged version of what i've got:
    Code:
    template <typename T> class List
    {
        public:
    
            ...
    
            class Iterator;
    
        private:
    
            class Node;
    
            Node *head, *tail;
    };
    
    template <typename T> class List<T>::Node
    {
        public:
    
            ...
    
        private:
    
            T data;
            Node *next, *prev;
    };
    
    template <typename T> class List<T>::Iterator
    {
        public:
    
            Iterator(Node* n) : node(n) {}
           ~Iterator() {}
    
            Iterator& operator++()
            {
                if (node != NULL)
                {
                    node = node->next;
                }
                return(*this);
            }
    
            Iterator& operator++(int)
            {
                Iterator i(*this);
                ++(*this);
                return(i);
            }
    
        private:
    
            Node *node;
    };
    as you can see, this is a doubly linked-list template class. My question is how can I implement an Iterator in a List member function?

    For example, if I have display() function, how do I use an Iterator for list traversal?

  2. #2
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >My question is how can I implement an Iterator in a List member function?
    You don't need to unless you're going for sheer simplicity of the implementation. The iterator is there for client code to traverse your list without having to know about the details of the implementation. So your list class would have something like this:
    Code:
    template <typename T>
    class List {
    public:
      // ...
      Iterator begin() { return Iterator ( head ); }
      Iterator end() { return Iterator ( tail ); }
    };
    Then, (assuming you've defined your list such that tail is one past the last item and head is the first item) clients can do this:
    Code:
    List<int> foo;
    
    // ...
    
    List<int>::Iterator it = foo.begin();
    List<int>::Iterator end = foo.end();
    
    while ( it != end ) {
      // Do something with it
    }
    My best code is written with the delete key.

  3. #3
    Registered Abuser
    Join Date
    Sep 2007
    Location
    USA/NJ/TRENTON
    Posts
    127
    what i'd like to do is something like:

    Code:
    template <typename T> void List<T>::display()
    {
        /*  Declare an Iterator  */
    
        while ( myIter != end )
        {
            /*  Display the Node data "T"  */
            
           myIter++;  // to advance to the next Node in the List
        }
    }
    what is troubling me is:

    1) how do I declare the Iterator in the member function with the class setup in my OP?

    2) how can I display something like the data (which belongs to Node) using the Iterator?

  4. #4
    The superhaterodyne twomers's Avatar
    Join Date
    Dec 2005
    Location
    Ireland
    Posts
    2,273
    1) List<T>::iterator iter;
    2) You could overload its << operator ...

  5. #5
    Registered Abuser
    Join Date
    Sep 2007
    Location
    USA/NJ/TRENTON
    Posts
    127
    I'm still having a problem...

    Even if I do just this:
    Code:
    template <typename T> void List<T>::display()
    {
        List<T>::Iterator i;
    }
    ...i get errors:

    E:\EricsStuff\Builds\list.cpp In member function `void List<T>::dis()':

    481 E:\EricsStuff\Builds\list.cpp expected `;' before "i"

    E:\EricsStuff\Builds\list.cpp In member function `void List<T>::dis() [with T = int]':

    17 E:\EricsStuff\Builds\driver.cpp instantiated from here

    481 E:\EricsStuff\Builds\list.cpp dependent-name ` List<T>::Iterator' is parsed as a non-type, but instantiation yields a type

    481 E:\EricsStuff\Builds\list.cpp say `typename List<T>::Iterator' if a type is meant

  6. #6
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    481 E:\EricsStuff\Builds\list.cpp say `typename List<T>::Iterator' if a type is meant
    It's rare that a compiler is this helpful.

    But actually, just saying Iterator should be enough.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  7. #7
    Registered Abuser
    Join Date
    Sep 2007
    Location
    USA/NJ/TRENTON
    Posts
    127
    Quote Originally Posted by CornedBee
    It's rare that a compiler is this helpful.
    That was compiled using MinGW: -ansi -pedantic -Wall, if you're wondering.

    I just got off of work, so it's too late to play around with this now (it almost Midnight)

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Ok, so sticking iterators inside a class is USUALLY not a good something you should do.

    In class design, the members of a class should be "what's necessary to solve the problem and ntohing more". If the iterator is going to be used like a for- or while-loop iterator variable, that is only used within a function, then it shouldn't be part of the class - it should be a local iterator in the function(s) that need the iteration.

    Note that this is for several reasons:
    1. Class members that aren't needed take up extra space for every instance of the class. Local variables only take up space when you are in the function using that variable.
    2. The more "stuff" there is in a class, the harder it is to do further work on it.
    3. It is harder to access a class member (from the compilers perspective) than a local variable in a function.
    4. The compiler may not realize how this variable is used and that it's actually not needed to be stroed back into the class when you are finished with it, that no other calls to member functions can't occur at this time, etc, etc, so the compiler will generate less good code (perhaps always storing any iterator changes back into the class, when this is completely unnecessary).

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    I don't think sh3rpa has actual instances of the iterator in the class.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by CornedBee View Post
    I don't think sh3rpa has actual instances of the iterator in the class.
    Ah, no, you are right. Sorry I wasted some space.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #11
    Registered Abuser
    Join Date
    Sep 2007
    Location
    USA/NJ/TRENTON
    Posts
    127
    Quote Originally Posted by CornedBee
    I don't think sh3rpa has actual instances of the iterator in the class.
    What exactly does that mean: *instances of the iterator in the class* ???

    I mean, the class *Iterator* itself IS declared in class List. I'm confused. I guess I've never known exactly what *instance* means. Please explain.

  12. #12
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Simply put, an instance is an object. So an instance of Iterator means an Iterator object.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Instance of a class is the "object that is of a type class".

    Code:
    class something {
    ... 
    };
    
    something *ptr;
    something aa;
    ptr = new something;
    ptr is (in the above codesegment) pointing to an instance of a class.
    likewise, aa is an instance of a class.

    So, if your iterator is part of your class, then that's (usually) wrong, as I explained earlier.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #14
    Registered Abuser
    Join Date
    Sep 2007
    Location
    USA/NJ/TRENTON
    Posts
    127
    ok thanx, i get the whole *instance* thing now.


    But if an Iterator is declared in a member function, then it's only local to that function, and therefore is NOT an instance of the class right?

    For example:
    Code:
    void myClass::my fucntion()
    {
        Iterator i;
    
        ...
    }
    Iterator i is only local, right?

  15. #15
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, that's exactly how your are supposed to do it. Local variable in the member function.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed