I'm not sure why all this is done this way. What advantage is there to this cryptic syntax? What can I do with this that is more powerful than using a foreach (if it existed)?
Also, If I want to pick a random element out of the list, I don't really know how, since I'm not sure how to convert the "std::map<std::string,GUI_widget *>::iterator" into an integer to use with rand(). I've read the relevant sections on sgi's reference, but that doesn't help, and I'm not having any success with search engines.
Thanks for any advice.

0

Share this post

Link to post

Share on other sites

1) That is essentially the same as a foreach loop. I don't personally use STL very much (I don't program at home as much anymore, and I don't use it at work since I need to keep executable sizes down), so I won't comment on the syntax of the iterator class.

2) If you want random access into a container, use a vector. Since vectors allow random access. A crude way would be to get a random integer between 0 and the number of elements and just iterate through the container and return the element at the random index. I'd just use a vector though (or wait for someone who uses STL to comment).

Also, there is a for_each() function in the standard library (although getting it to do what you want can occasionally require jumping through some hoops).

As for picking a random element, a map is not a random-access container, so you can't just index into it using a random value. You should however be able to achieve essentially the same thing by using std::advance().

Share this post

Link to post

Share on other sites

Original post by jykHm, that example is pretty confusing. If I'm reading it right, it really should just be:

*** Source Snippet Removed ***Also, there is a for_each() function in the standard library (although getting it to do what you want can occasionally require jumping through some hoops).

As for picking a random element, a map is not a random-access container, so you can't just index into it using a random value. You should however be able to achieve essentially the same thing by using std::advance().

Thanks for your answers,

I tried defining a new type instead of using the std::container<types>::extra::conceptual::overhead::iterator syntax repeatedly, but got a linker error.

Is there an indexed container that allows random access?

why it->second rather than it->first? (Is that why my code has a bizarre error where I can dump all child widgets in a list but not pass stuff down the heirarchy?

The point of this (very crude: only buttons and windows) OpenGL GUI project is to learn about STL containers. I've got it drawing nicely, so not everything was a waste of time.

I'll look deeper into a c++ for_each. I would really like to just say for_each(children, GUI_widget * child){} or something similar.

0

Share this post

Link to post

Share on other sites

That iterator syntax is more or less standard. Like a lot of things in C++, it's very verbose but that can't be avoided. One thing you can do is jyk suggested and use a typedef to reduce the length of the map type. If you do that, you can declare the iterator inside the for statement and it looks less bulky and is easier to read.

As for your loop being inefficient, it's doing unnecessary lookups. A map is implemented as a binary tree and the iterator as (I'm guessing) a depth-first traversal. Looking up a specific element in a binary tree takes time, but the iterator has already traversed to that element so there's no need to look it up again. You can just call it->second->handle_event(E).

And picking a random element is easy. You know the size of the map from with size method, and you can get an iterator on the first element with the begin method. After that, there's an advance function you can use, or you can use a for loop and increment the iterator.

Share this post

Link to post

Share on other sites

Original post by jonahrowleyThat iterator syntax is more or less standard. Like a lot of things in C++, it's very verbose but that can't be avoided. One thing you can do is jyk suggested and use a typedef to reduce the length of the map type. If you do that, you can declare the iterator inside the for statement and it looks less bulky and is easier to read.

As for your loop being inefficient, it's doing unnecessary lookups. A map is implemented as a binary tree and the iterator as (I'm guessing) a depth-first traversal. Looking up a specific element in a binary tree takes time, but the iterator has already traversed to that element so there's no need to look it up again. You can just call it->second->handle_event(E).

And picking a random element is easy. You know the size of the map from with size method, and you can get an iterator on the first element with the begin method. After that, there's an advance function you can use, or you can use a for loop and increment the iterator.

why it->second rather than it->first? (Is that why my code has a bizarre error where I can dump all child widgets in a list but not pass stuff down the heirarchy?

When you iterate over a map, you iterate over the map's pair element. If you have a map<string,int>, then the iterator points to a pair<string,int>. The pair has 2 methods of interest, first and second. The first method will return the string, the second method will return the int.

Quote:

I'll look deeper into a c++ for_each. I would really like to just say for_each(children, GUI_widget * child){} or something similar.

Sadly, you can't do that yet. The next version of C++ (called C++0x) will have lambdas (also called closures or anonymous functions). Then you'll be able to do that. Right now, you have to do something like this.

As you can see, the actual code to be run by the for_each algorithm is disjointed from the for_each call itself. This is why people use the for loop with an iterator instead of a for_each call. This will be better in C++0x, you'll be able to do something like this.

Share this post

Link to post

Share on other sites

Original post by speciesUnknowner... I was under the impression that you can contaminate a namespace if you say using namespace? In what circumstances can this happen?

That depends on your code. For small programs, there's no reason not to do it. For large programs, there are few reasons not to do it. You "contaminate" the global namespace with all the symbols from the std namespace, but that's usually not a problem. Of course, if you're using your own namespaces, importing everything from std into them is probably not a good idea.