Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > STL list::iterator problem

Reply
Thread Tools

STL list::iterator problem

 
 
jayesah@gmail.com
Guest
Posts: n/a
 
      11-24-2006
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

 
Reply With Quote
 
 
 
 
Markus Moll
Guest
Posts: n/a
 
      11-24-2006
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

 
Reply With Quote
 
 
 
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      11-24-2006
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
 
Reply With Quote
 
eriwik@student.chalmers.se
Guest
Posts: n/a
 
      11-24-2006
On Nov 24, 1:34 pm, jaye...@gmail.com 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

 
Reply With Quote
 
Daniel T.
Guest
Posts: n/a
 
      11-24-2006
In article < .com>,
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.
 
Reply With Quote
 
Jim Langston
Guest
Posts: n/a
 
      11-24-2006
<> wrote in message
news: oups.com...
> 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...



 
Reply With Quote
 
jayesah@gmail.com
Guest
Posts: n/a
 
      11-25-2006

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 ?

 
Reply With Quote
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      11-25-2006
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
 
Reply With Quote
 
jayesah@gmail.com
Guest
Posts: n/a
 
      11-25-2006

Daniel T. wrote:
> In article < .com>,
> 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..........

 
Reply With Quote
 
Daniel T.
Guest
Posts: n/a
 
      11-25-2006
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.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Segmentation Fault on stl::resize / stl::clear Steve C++ 2 11-06-2007 06:53 AM
stl questions: how can I compare 2 stl list? silverburgh.meryl@gmail.com C++ 5 04-16-2006 09:57 PM
a stl map which use stl pair as the key Allerdyce.John@gmail.com C++ 2 02-22-2006 07:25 AM
Copy elements from one STL container to another STL container Marko.Cain.23@gmail.com C++ 4 02-16-2006 05:03 PM
To STL or not to STL Allan Bruce C++ 41 10-17-2003 08:21 PM



Advertisments