STL list::iterator problem

Discussion in 'C++' started by jayesah@gmail.com, Nov 24, 2006.

  1. Guest

    Hi All,

    List and its iterator work as following way :

    list<int> mylist;
    list<int>::iterator itr;
    itr = mylist.begin();
    cout << (*itr);

    But I want something like this:

    list<int> mylist;
    MyIterator itr(mylist);
    cout<< (*itr);


    So I wrote MyIterator following way :

    template <class T> class MyIterator : public list<T>::iterator
    {
    public:
    MyIterator() { };

    ~MyIterator() { };

    MyIterator(list<T>& mylist) {

    /* What I should write here */
    };
    };

    int main()
    {
    list<int> mylist;
    mylist.push_back(1);
    mylist.push_back(2);

    /* I want to support following construct */

    MyIterator iter(mylist);
    cout <<*mylist;

    return 0;
    }

    Can anybody please guide me what I should write in one parameter
    constructor ? Or do you have all together different solution ?

    The reason I derived MyIterator from list<T>::iterator is that I want
    to support all the overloaded operator that list<T>::iterator supports.

    Thanks
    Jayesh Shah
     
    , Nov 24, 2006
    #1
    1. Advertising

  2. Markus Moll Guest

    Hi

    wrote:

    > List and its iterator work as following way :
    >
    > list<int> mylist;
    > list<int>::iterator itr;
    > itr = mylist.begin();
    > cout << (*itr);
    >
    > But I want something like this:
    >
    > list<int> mylist;
    > MyIterator itr(mylist);
    > cout<< (*itr);


    What is the difference? MyIterator will need to be some template, as
    otherwise you cannot distinguish different element types. So it would
    probably be MyIterator<int>. I can't see any difference to
    list<int>::iterator.

    Markus
     
    Markus Moll, Nov 24, 2006
    #2
    1. Advertising

  3. Kai-Uwe Bux Guest

    wrote:

    > Hi All,
    >
    > List and its iterator work as following way :
    >
    > list<int> mylist;
    > list<int>::iterator itr;
    > itr = mylist.begin();
    > cout << (*itr);
    >
    > But I want something like this:
    >
    > list<int> mylist;
    > MyIterator itr(mylist);
    > cout<< (*itr);


    Why? Looks like a BadIdea(tm) to me.



    > So I wrote MyIterator following way :
    >
    > template <class T> class MyIterator : public list<T>::iterator


    Note: there is no guarantee that list<T>::iterator is inheritable. However,
    this will not be a problem in practice since, as far as I know, all widely
    used implementations implement list<>::iterator as a class without
    finalizing trickery.


    > {
    > public:
    > MyIterator() { };
    >
    > ~MyIterator() { };
    >
    > MyIterator(list<T>& mylist) {
    >
    > /* What I should write here */
    > };


    You need to construct the base:

    MyIterator ( list<T> & mylist )
    : list<T>::iterator( mylist.begin() )
    {}

    (untested)

    > };
    >
    > int main()
    > {
    > list<int> mylist;
    > mylist.push_back(1);
    > mylist.push_back(2);
    >
    > /* I want to support following construct */
    >
    > MyIterator iter(mylist);
    > cout <<*mylist;
    >
    > return 0;
    > }


    And how do you intend to use these iterators in a loop:

    MyIterator itr ( mylist );
    while ( itr != ??? ) {
    ...
    ++itr;
    }


    > Can anybody please guide me what I should write in one parameter
    > constructor ? Or do you have all together different solution ?


    Yes: use mylist.begin() and mylist.end().

    [snip]


    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Nov 24, 2006
    #3
  4. Guest

    On Nov 24, 1:34 pm, wrote:
    > Hi All,
    >
    > List and its iterator work as following way :
    >
    > list<int> mylist;
    > list<int>::iterator itr;
    > itr = mylist.begin();
    > cout << (*itr);
    >
    > But I want something like this:
    >
    > list<int> mylist;
    > MyIterator itr(mylist);
    > cout<< (*itr);


    I'll admit that I have not tested this but I'm quite sure that
    STL-iterators have a copy-constructor so something like this ought to
    work:

    #include <list>
    #include <iostream>

    typedef MyList std::list<int>
    typedef MyIterator std::list<int>::iterator

    MyList l;
    MyIterator itr(l.begin());
    std::cout << *itr;

    >template <class T> class MyIterator : public list<T>::iterator
    >{
    > public:
    > MyIterator() { };
    >
    > ~MyIterator() { };
    >
    > MyIterator(list<T>& mylist) {
    >
    > /* What I should write here */
    > };
    >
    >};


    If you realy want to do it your way I think you need to initialize the
    base of your derived class like this (again, untested):

    #include <list>
    #include <iostream>

    template <class T> class MyIterator : public list<T>::iterator
    {
    MyIterator (std::list<T>& l)
    : std::list<T>::iterator(l.begin())
    { };
    };

    int main()
    {
    std::list<int> l;
    l.push_back(2);
    MyIterator<int> iter(l);
    std::cout << *iter;
    return 0;
    }

    Notice the template parameter, like Markus pointed out, when creating
    an instance of the MyIterator-class.

    --
    Erik Wikström
     
    , Nov 24, 2006
    #4
  5. Daniel T. Guest

    In article <>,
    wrote:

    > Hi All,
    >
    > List and its iterator work as following way :
    >
    > list<int> mylist;
    > list<int>::iterator itr;
    > itr = mylist.begin();
    > cout << (*itr);
    >
    > But I want something like this:
    >
    > list<int> mylist;
    > MyIterator itr(mylist);
    > cout<< (*itr);


    Why? What problem does this solve? I can understand writing algorithms
    that take whole containers rather than 'begin' and 'end' but this? I
    don't get it.

    > So I wrote MyIterator following way :
    >
    > template <class T> class MyIterator : public list<T>::iterator
    > {
    > public:
    > MyIterator() { };
    >
    > ~MyIterator() { };
    >
    > MyIterator(list<T>& mylist) {
    >
    > /* What I should write here */
    > };
    > };
    >
    > int main()
    > {
    > list<int> mylist;
    > mylist.push_back(1);
    > mylist.push_back(2);
    >
    > /* I want to support following construct */
    >
    > MyIterator iter(mylist);
    > cout <<*mylist;
    >
    > return 0;
    > }
    >
    > Can anybody please guide me what I should write in one parameter
    > constructor ? Or do you have all together different solution ?
    >
    > The reason I derived MyIterator from list<T>::iterator is that I want
    > to support all the overloaded operator that list<T>::iterator supports.


    What about all the other iterators? Anything you write in MyIterator
    should work just as well with any other bi-directional iterator yet you
    only derived from list<T>::iterator. That seems quite limiting.

    I have an idea though...

    template < typename Con >
    class MyIterator
    {
    Con& container;
    typename Con::iterator pos;
    public:
    typedef typename Con::reference reference;

    MyIterator( Con& c ): container( c ), pos( c.begin() ) { }

    reference operator*() {
    return *pos;
    }
    };

    int main() {
    list<int> myList;
    MyIterator<list<int> > itr( myList );
    cout << (*itr);
    }

    --
    To send me email, put "sheltie" in the subject.
     
    Daniel T., Nov 24, 2006
    #5
  6. Jim Langston Guest

    <> wrote in message
    news:...
    > Hi All,
    >
    > List and its iterator work as following way :
    >
    > list<int> mylist;
    > list<int>::iterator itr;
    > itr = mylist.begin();
    > cout << (*itr);
    >
    > But I want something like this:
    >
    > list<int> mylist;
    > MyIterator itr(mylist);
    > cout<< (*itr);
    >
    >
    > So I wrote MyIterator following way :
    >
    > template <class T> class MyIterator : public list<T>::iterator
    > {
    > public:
    > MyIterator() { };
    >
    > ~MyIterator() { };
    >
    > MyIterator(list<T>& mylist) {
    >
    > /* What I should write here */
    > };
    > };
    >
    > int main()
    > {
    > list<int> mylist;
    > mylist.push_back(1);
    > mylist.push_back(2);
    >
    > /* I want to support following construct */
    >
    > MyIterator iter(mylist);
    > cout <<*mylist;
    >
    > return 0;
    > }
    >
    > Can anybody please guide me what I should write in one parameter
    > constructor ? Or do you have all together different solution ?
    >
    > The reason I derived MyIterator from list<T>::iterator is that I want
    > to support all the overloaded operator that list<T>::iterator supports.
    >
    > Thanks
    > Jayesh Shah


    I think the problem you're going to run into is that mylist really doesn't
    know what it is. That is, you really want:
    MyIterator iter(mylist);
    to expand to
    MyIterator iter(list<int>);
    or the like (although that above won't compile I"m sure).

    I understand why you want to do this, and it would be nice, but I really
    don't think it's possible The way I deal with it is by using typedef.

    typedef list<int> DataList;

    DataList MyList;
    DataList::iterator it = MyList.begin();
    std::cout << (*itr);

    I don't really think you can generically create an iterator off a generic
    container. It would be nice if you could, but still, what if it's a map?
    Then you have .first() and .second() which a list doesn't have, etc...
     
    Jim Langston, Nov 24, 2006
    #6
  7. Guest

    Kai-Uwe Bux wrote:
    > wrote:
    >
    > > Hi All,
    > >
    > > List and its iterator work as following way :
    > >
    > > list<int> mylist;
    > > list<int>::iterator itr;
    > > itr = mylist.begin();
    > > cout << (*itr);
    > >
    > > But I want something like this:
    > >
    > > list<int> mylist;
    > > MyIterator itr(mylist);
    > > cout<< (*itr);

    >
    > Why? Looks like a BadIdea(tm) to me.
    >
    >
    >
    > > So I wrote MyIterator following way :
    > >
    > > template <class T> class MyIterator : public list<T>::iterator

    >
    > Note: there is no guarantee that list<T>::iterator is inheritable. However,
    > this will not be a problem in practice since, as far as I know, all widely
    > used implementations implement list<>::iterator as a class without
    > finalizing trickery.
    >
    >
    > > {
    > > public:
    > > MyIterator() { };
    > >
    > > ~MyIterator() { };
    > >
    > > MyIterator(list<T>& mylist) {
    > >
    > > /* What I should write here */
    > > };

    >
    > You need to construct the base:
    >
    > MyIterator ( list<T> & mylist )
    > : list<T>::iterator( mylist.begin() )
    > {}
    >
    > (untested)
    >
    > > };
    > >
    > > int main()
    > > {
    > > list<int> mylist;
    > > mylist.push_back(1);
    > > mylist.push_back(2);
    > >
    > > /* I want to support following construct */
    > >
    > > MyIterator iter(mylist);
    > > cout <<*mylist;
    > >
    > > return 0;
    > > }

    >
    > And how do you intend to use these iterators in a loop:
    >
    > MyIterator itr ( mylist );
    > while ( itr != ??? ) {
    > ...
    > ++itr;
    > }
    >
    >
    > > Can anybody please guide me what I should write in one parameter
    > > constructor ? Or do you have all together different solution ?

    >
    > Yes: use mylist.begin() and mylist.end().
    >
    > [snip]
    >
    >
    > Best
    >
    > Kai-Uwe Bux


    Thanks a lot Bux.
    You said there is no guarantee that list<T>::iterator is inheritable.
    Is it defined in spec ?
    How come you implement a iterator without the class since you have lots
    of operator to overload ?
     
    , Nov 25, 2006
    #7
  8. Kai-Uwe Bux Guest

    wrote:


    > Thanks a lot Bux.
    > You said there is no guarantee that list<T>::iterator is inheritable.
    > Is it defined in spec ?


    By "spec" you mean the C++ standard? No, it's not defined in the standard.
    That's why there is no guarantee. The type list<T>::iterator is marked
    as "implementation defined".

    For std::vector<T>, for instance, an implementation is free to use T* as an
    iterator. In that case, std::vector<T>::iterator would not be a class.

    For std::list<T>, an implementation is free to use trickery (using virtual
    base classes) to prevent inheritance. (Although, to my knowledge, no
    implementation actually does that.)


    > How come you implement a iterator without the class since you have lots
    > of operator to overload ?


    Huh? I do not understand, and I think that sentence just does not parse. I
    am not a native speaker of English, so my parser has little tolerance and
    is very limited with regard to error correction.


    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Nov 25, 2006
    #8
  9. Guest

    Daniel T. wrote:
    > In article <>,
    > wrote:
    >
    > > Hi All,
    > >
    > > List and its iterator work as following way :
    > >
    > > list<int> mylist;
    > > list<int>::iterator itr;
    > > itr = mylist.begin();
    > > cout << (*itr);
    > >
    > > But I want something like this:
    > >
    > > list<int> mylist;
    > > MyIterator itr(mylist);
    > > cout<< (*itr);

    >
    > Why? What problem does this solve? I can understand writing algorithms
    > that take whole containers rather than 'begin' and 'end' but this? I
    > don't get it.
    >
    > > So I wrote MyIterator following way :
    > >
    > > template <class T> class MyIterator : public list<T>::iterator
    > > {
    > > public:
    > > MyIterator() { };
    > >
    > > ~MyIterator() { };
    > >
    > > MyIterator(list<T>& mylist) {
    > >
    > > /* What I should write here */
    > > };
    > > };
    > >
    > > int main()
    > > {
    > > list<int> mylist;
    > > mylist.push_back(1);
    > > mylist.push_back(2);
    > >
    > > /* I want to support following construct */
    > >
    > > MyIterator iter(mylist);
    > > cout <<*mylist;
    > >
    > > return 0;
    > > }
    > >
    > > Can anybody please guide me what I should write in one parameter
    > > constructor ? Or do you have all together different solution ?
    > >
    > > The reason I derived MyIterator from list<T>::iterator is that I want
    > > to support all the overloaded operator that list<T>::iterator supports.

    >
    > What about all the other iterators? Anything you write in MyIterator
    > should work just as well with any other bi-directional iterator yet you
    > only derived from list<T>::iterator. That seems quite limiting.
    >
    > I have an idea though...
    >
    > template < typename Con >
    > class MyIterator
    > {
    > Con& container;
    > typename Con::iterator pos;
    > public:
    > typedef typename Con::reference reference;
    >
    > MyIterator( Con& c ): container( c ), pos( c.begin() ) { }
    >
    > reference operator*() {
    > return *pos;
    > }
    > };
    >
    > int main() {
    > list<int> myList;
    > MyIterator<list<int> > itr( myList );
    > cout << (*itr);
    > }
    >
    > --
    > To send me email, put "sheltie" in the subject.



    Absolutely a brilliant solution.....

    You suggested the usage as :
    MyIterator<list<int> > itr( myList );

    But I want to use as

    MySlistIterator itr(list); // I can not change this usage

    So what I thought is

    template<class T> typedef MyIterator<list< T > > MySlisIterator<T>;

    but this is not supported in c++..what can be the alternative ??

    Thanks a lot again..........
     
    , Nov 25, 2006
    #9
  10. Daniel T. Guest

    wrote:

    > You suggested the usage as :
    > MyIterator<list<int> > itr( myList );
    >
    > But I want to use as
    >
    > MySlistIterator itr(list); // I can not change this usage


    Why? What problem does this solve?

    --
    To send me email, put "sheltie" in the subject.
     
    Daniel T., Nov 25, 2006
    #10
  11. Guest

    Daniel T. wrote:
    > wrote:
    >
    > > You suggested the usage as :
    > > MyIterator<list<int> > itr( myList );
    > >
    > > But I want to use as
    > >
    > > MySlistIterator itr(list); // I can not change this usage

    >
    > Why? What problem does this solve?
    >
    > --
    > To send me email, put "sheltie" in the subject.



    I am replacing existing code, which has the syntax, I described.
     
    , Nov 27, 2006
    #11
  12. Daniel T. Guest

    wrote:
    > Daniel T. wrote:
    >> wrote:
    >>
    >>> You suggested the usage as : MyIterator<list<int> > itr( myList );
    >>>
    >>> But I want to use as
    >>>
    >>> MySlistIterator itr(list); // I can not change this usage

    >>
    >> Why? What problem does this solve?

    >
    > I am replacing existing code, which has the syntax, I described.


    And you have to maintain the same interface? In that case, show me the
    interface of MySlistIterator and I'll see if I can help.

    --
    To send me email, put "sheltie" in the subject.
     
    Daniel T., Nov 27, 2006
    #12
  13. Guest

    Daniel T. wrote:
    > wrote:
    > > Daniel T. wrote:
    > >> wrote:
    > >>
    > >>> You suggested the usage as : MyIterator<list<int> > itr( myList );
    > >>>
    > >>> But I want to use as
    > >>>
    > >>> MySlistIterator itr(list); // I can not change this usage
    > >>
    > >> Why? What problem does this solve?

    > >
    > > I am replacing existing code, which has the syntax, I described.

    >
    > And you have to maintain the same interface? In that case, show me the
    > interface of MySlistIterator and I'll see if I can help.
    >
    > --
    > To send me email, put "sheltie" in the subject.



    MySlistIterator itr(list);

    while( itr() )
    {
    cout << *itr;

    }
     
    , Nov 28, 2006
    #13
  14. Daniel T. Guest

    wrote:
    > Daniel T. wrote:
    >> wrote:
    >>> Daniel T. wrote:
    >>>> wrote:
    >>>>
    >>>>> You suggested the usage as : MyIterator<list<int> > itr( myList
    >>>>> );
    >>>>>
    >>>>> But I want to use as
    >>>>>
    >>>>> MySlistIterator itr(list); // I can not change this usage
    >>>>
    >>>> Why? What problem does this solve?
    >>>
    >>> I am replacing existing code, which has the syntax, I described.

    >>
    >> And you have to maintain the same interface? In that case, show me
    >> the interface of MySlistIterator and I'll see if I can help.

    >
    > MySlistIterator itr(list);
    >
    > while( itr() )
    > {
    > cout << *itr;
    > }


    That isn't an interface. What are the public member-functions that
    MySlistIterator must support? What does the existing MySlistIterator
    class look like?

    class MySlistIterator
    {
    public:
    // what's here?
    };

    --
    To send me email, put "sheltie" in the subject.
     
    Daniel T., Nov 28, 2006
    #14
  15. Guest

    Daniel T. wrote:
    > wrote:
    > > Daniel T. wrote:
    > >> wrote:
    > >>> Daniel T. wrote:
    > >>>> wrote:
    > >>>>
    > >>>>> You suggested the usage as : MyIterator<list<int> > itr( myList
    > >>>>> );
    > >>>>>
    > >>>>> But I want to use as
    > >>>>>
    > >>>>> MySlistIterator itr(list); // I can not change this usage
    > >>>>
    > >>>> Why? What problem does this solve?
    > >>>
    > >>> I am replacing existing code, which has the syntax, I described.
    > >>
    > >> And you have to maintain the same interface? In that case, show me
    > >> the interface of MySlistIterator and I'll see if I can help.

    > >
    > > MySlistIterator itr(list);
    > >
    > > while( itr() )
    > > {
    > > cout << *itr;
    > > }

    >
    > That isn't an interface. What are the public member-functions that
    > MySlistIterator must support? What does the existing MySlistIterator
    > class look like?
    >
    > class MySlistIterator
    > {
    > public:
    > // what's here?
    > };
    >
    > --
    > To send me email, put "sheltie" in the subject.


    MySlistIterator is implemented in a custom library which source code is
    not available. Thats why I have only the usage interface and nothing
    much.

    So I planned to create a iterator class for each collection. But I
    liked your solution: one iterator for all collection. Unfortunately I
    am not allowed to change the existing source code, and template typedef
    syntax is not supported in C++, I am not able to use your solution.
     
    , Nov 29, 2006
    #15
  16. Daniel T. Guest

    wrote:
    > Daniel T. wrote:
    >
    >> What are the public member-functions that MySlistIterator must
    >> support? What does the existing MySlistIterator class look like?
    >>
    >> class MySlistIterator
    >> {
    >> public:
    >> // what's here?
    >> };

    >
    > MySlistIterator is implemented in a custom library which source code
    > is not available. Thats why I have only the usage interface and
    > nothing much.


    I'm not asking for the source code. Post the class definition from the
    header.

    --
    To send me email, put "sheltie" in the subject.
     
    Daniel T., Nov 29, 2006
    #16
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    6
    Views:
    651
    Jim Langston
    Oct 30, 2005
  2. Jonathan
    Replies:
    6
    Views:
    412
    Jonathan
    Mar 14, 2006
  3. maverick

    STL List iterator

    maverick, Oct 24, 2006, in forum: C++
    Replies:
    7
    Views:
    321
    red floyd
    Oct 25, 2006
  4. Olumide
    Replies:
    10
    Views:
    632
    Richard Herring
    Sep 17, 2007
  5. David Bilsby
    Replies:
    5
    Views:
    2,047
    David Bilsby
    Oct 9, 2007
Loading...

Share This Page