Sign in to follow this  

iterators to a list of class pointers ...

This topic is 4861 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

for some reason i cannot figure this out, i could just use a vector but this is driving me crazy (i'm probably missing something stupid again ... i googled but only found stuff on sorting a list of pointers) anyways ... for example ... std::vector < myClass * > v; for (int n = 0; n < v.size (); n ++) { v[n] -> memberFunction_01; v[n] -> memberFunction_02; } now this is where i'm stuck ... since lists are liner i can't use [] ... so how the heck do you do this? im stumped on the syntax ... std::list < myClass * > l; std::list < myClass * > :: iterator i = l.begin (); while (i != l.end ()) { i -> ... well then ... } well i guess i could overload [] operator to make my list like a vector ... can you do this? or doing something like this just reserved for vectors? thanks for any help

Share this post


Link to post
Share on other sites
augh, sorry I misread that, ignore that post..
unless you overload the operators if you want to index into a specific one, that'll be the only way (it'll still have to traverse down the nodes though). Vectors are fine, just use .reserve() to avoid having the data relocate itself.

Share this post


Link to post
Share on other sites
yeah i wasn't sure you could index an iterator to a list, but it looked like it was right ... so basically there is no solution haha ... so it looks like i have to use a vector to do this ... which brings me to conclude why use a list when you can use a vector?

Share this post


Link to post
Share on other sites
if i read your original post right, you are looking for this:

std::list<Whatever*> things;
for (std::list<Whatever*>::iterator iter = things.begin(); iter != things.end(); iter++) {
(*iter)->MemberFunction();
}


You cannot index into the list. Arrays and vectors work off the fact that the memory in those arrays or vectors are all in one block. A std::list is a linked list whereas a vector is more like an array.

Vectors suffer from the fact that they must keep that memory in order. A linked list does not care. So every time you add to or erase a vector element from the middle of the vector, everything after that element has to get shuffled back or forward to keep everything contiguous. A list would simply have to relink.

Use a vector if insertion or deletion in the beginning or middle is not required much but retrieval speed is needed. Use a list if retrieval speed is not a big deal but you do a lot of insertion and deletion from everywhere in the list.

Example: my game has a list of objects in the game that need per-frame updating. I use a std::list for that since when i iterate over them, i do so in order every frame and i never need random access to the elements, and also because i add and remove things from the list constantly. I would not dare use a vector for that, especially as there might be thousands of things in the list.

Share this post


Link to post
Share on other sites
ok that makes sense, this is exactly what im applying this to, i have a large list of refrences to differnt objects all of same base class, since i will have to insert and delete objects from that list, using a list would be much better ...

(*iter)->someFunc ();

so does the iterator type overload unary * to defrence itself? is this what is happening?

Share this post


Link to post
Share on other sites
Quote:
Original post by ekrax
so does the iterator type overload unary * to defrence itself? is this what is happening?


For list yes the iterator type for list overloads the dereference operator, all user-defined iterators are written to act like a pointers so not only can use library containers with algorithms that take iterators you can also use pointers to arrays aswell, this is static polymoprhism through templates example:


#include <iterator>
#include <algorithm>
#include <iostream>

int main() {

int A[] = { 1, 4, 2, 8, 5, 7 };
const int N = sizeof(A) / sizeof(int);
std::sort(A, A + N);
std::copy(A, A + N, std::ostream_iterator<int>(std::cout, ", "));

return 0;
}


Share this post


Link to post
Share on other sites
Quote:
Original post by ekrax
so does the iterator type overload unary * to defrence itself? is this what is happening?


Yes, basically. It derefernces the iterator, not the pointer it iterates to. Keep in mind that it may not even be a pointer that you are containing in the list.

(*iter)->Function();

// call the function of a pointer held by the iterator


iter->Function();

// call the function of the iterator

Share this post


Link to post
Share on other sites
Or in other words:

std::list<myClass *> l;

// push something into the list, then...

std::list<myClass *>::iterator it=l.begin ();

myClass *ptr = *it;
myClass &ref = **it;

ptr->memFunc ();
ref.memFunc ();


Share this post


Link to post
Share on other sites
Quote:
Original post by leiavoia

iter->Function();

// call the function of the iterator


That's not true. iter->Function calls "Function" on the contained type. For instance, if you had a list<myClass>::iterator, iter->Function () calls myClass::Function.

Iterators actually do have functions, and you call them with the . operator. For instance, std::reverse_iterator has a member function "base" which returns a forward iterator sort-of from the current position (it's very complicated), but you call it as follows:

list<myClass*>::reverse_iterator rIt = l.rbegin ();
// .. do some stuff..
(*rIt)->Function (); // call a myClass function
list<myClass*>::iterator it;
it = rIt.base (); // returns a bidirectional iterator one before wher rIt was pointing


Now, I suggest never converting from reverse to forward iterators if you can ever help it, but this is how you call a function of an iterator.

Share this post


Link to post
Share on other sites
Quote:
Original post by Stoffel
Quote:
Original post by leiavoia

iter->Function();

// call the function of the iterator


That's not true. iter->Function calls "Function" on the contained type. For instance, if you had a list<myClass>::iterator, iter->Function () calls myClass::Function.

Iterators actually do have functions, and you call them with the . operator. For instance, std::reverse_iterator has a member function "base" which returns a forward iterator sort-of from the current position (it's very complicated), but you call it as follows:
*** Source Snippet Removed ***
Now, I suggest never converting from reverse to forward iterators if you can ever help it, but this is how you call a function of an iterator.


mostly true, but it gets weirder, consider this:


std::map< std::string, std::string >::iterator iter = some_map.begin();
std::string a_string = iter->second; // note syntax

Share this post


Link to post
Share on other sites
Hi,

Quote:
Original post by leiavoia
mostly true, but it gets weirder, consider this:

*** Source Snippet Removed ***


Well, it's really not so weird if you think about it. [smile] I mean, what is the map really? You can think of it as being equivalent to a list of pairs:


std::map<key_type, value_type> === std::vector< std::pair<key_type, value_type> >


Now, if you have an iterator for that map, then what are you really iterating over? That's right, the pairs. So, when you say:


value_type v = iter->second


That is really equivalent to saying:


value_type v = (*iter).second;


Then that makes sense, because what is *iter? It's just a pair. [smile]

Of course, if you wanted to implement your own map as a list of pair pointers, then you could do:


typedef mymap std::vector< std::pair<key_type, value_type>* >;


And then when you iterate over the map, to reference the value, you'd have to do:


value_type v = (*iter)->second;


Talk about weird. [wink]

Vovan

Share this post


Link to post
Share on other sites

This topic is 4861 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this