Skip to main content
GameDev.net gamedev.net
🔒 Locked

Defining Iterators for Nested Containers

Started by chaospilot Mar 17, 2007 at 7:36 PM 7 replies 1.1k views
Original Post
chaospilot
chaospilot
I've looked online and in a book for help and can't seem to define an iterator for my container class yet. I'm trying to delegate, since it's a relatively simple container. I'm using the following class (the following is reduced to its basis, there are a lot of methods defined to give it the desired container traits): template class Profile { private: typedef list< pair > ProfileData; ProfileData data; // I have now (but I cant decipher the errors): public: typedef ProfileData::iterator iterator; typedef ProfileData::const_iterator const_iterator; } I want the end user to be able to write: Profile mProf; // Add data to mProf Profile::iterator pIt; for(pIt = mProf.begin(); pIt != mProf.end(); pIt++) { // Do stuff } What is the right way to do this (code cleanup appreciated too! :) )? 2nd question: Is it generally encouraged to ask questions on the forums here when learning a new topic (after doing research and attempting to solve the problem) even though I haven't spent several days trying out various solutions. That is... for how long should one attempt to solve a problem before coming to the boards when learning completely new areas of programming?
iMalc
iMalc
In order for others to provide the best answer, it is important that you show all of the data members in the container, and perhaps a description of how they are manipulated. As at the moment the best answer would be to just use a std::list and not write your own container. People need to see why it is necessary to go furthur than that.

Don't worry, you seem to be asking for help at about the right stage.
chaospilot
chaospilot
The data member is a list of pairs of double (time values) associated with type T (Matrix/Quaternion/double/int/bool). This is the main input output container for reading, storing, passing around and writing data to a simulation state. The state will later be edited and checked for various constraints and such.

As such, the container has some constraints that make it relatively simple. The catch here is this is going to be used by engineers that have only a small bit of coding experience. I want them to see the Profile as a container that knows what to do when they want to perform set algebra on it (max(), min(), average(), getAtTime(), getLast(), ==, =, addData()). Those methods are all in and work fine, but I would like a transparent way of explicity creating loops without making them write list< pair< double, Matrix> >::iterator thisIsMyIt. And I dont want to use for_each and function pointers (it may be too complex).

From what I've read, I can explicitly define an iterator for my class, and simply make the iterator delegate the work to the STL iterators for my data member variable. I've tried 3 implementations on this directly from the internet and a book and all 3 give me compile time errors.
Zakwayda
Zakwayda
Short answer: within the context of the Profile class, ProfileData::iterator and ProfileData::const_iterator are dependent types, so you need to use the typename keyword:
typedef typename ProfileData::iterator iterator; typedef typename ProfileData::const_iterator const_iterator;
I'll go ahead and post this (as I'm sure others are posting even as I write this), but maybe I or someone else will be able to follow up in another post with an explanation of why this is necessary.
Zakwayda
Zakwayda
Here you go. Check out the 'Dependent Names' section, about halfway down.
chaospilot
chaospilot
Awesome, works great. Thanks for the reasoning too, I always try and learn on my own, but sometimes I get stuck because I still don't understand the "big picture" as it were. Kudospoints all around!
iMalc
iMalc
Quote:
Original post by chaospilot
I would like a transparent way of explicity creating loops without making them write list< pair< double, Matrix> >::iterator thisIsMyIt. And I dont want to use for_each and function pointers (it may be too complex).
Are you sure that a simple typedef wouldn't suffice in that case, in much the same way that there is no std::string class (it too is just a typedef)?
chaospilot
chaospilot
I'm actually not sure what the right answer to your question is. We might be able to get away with just a typedef, but at the moment I think we're looking at specifying unique operator functions for profiles, sorts, merges, accessor functions, and time-based lookups. There's really some optimization we can do with the class and lookups since we have an idea how they're gong to be used that I'm not sure we could do with a typedef...

Then again, I could be wrong and have to redo the whole thing, but I think it will be fun to explore this route! :)
iMalc
iMalc
Quote:
Original post by chaospilot
I'm actually not sure what the right answer to your question is. We might be able to get away with just a typedef, but at the moment I think we're looking at specifying unique operator functions for profiles, sorts, merges, accessor functions, and time-based lookups. There's really some optimization we can do with the class and lookups since we have an idea how they're gong to be used that I'm not sure we could do with a typedef...

Then again, I could be wrong and have to redo the whole thing, but I think it will be fun to explore this route! :)
Indeed. Best of luck with that eh![smile]

I've done that myself before (for good reason), and you have to do quite a bit to make sure it can do everything that someone might expect of it. Don't forget reverse iterators, for example.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.