joeware - never stop exploring... :)

Information about joeware mixed with wild and crazy opinions...

STL Iterators

by @ 4:20 pm on 7/9/2006. Filed under tech

The summary of this post is that if you are using a c++ Standard Template Library (STL) container and you need to iterate through it… use an iterator… That is what they are there for.

I admit, I am not the greatest c++ coder but I can generally find my way around without too much damage. Like many coders there are certain things you see in other’s code that just irk me when I see it and I am sure there are a ton of things I do that will irk others but they can go write their own blog entries… 

Four of the top things that irk me are

  • Excessive goto statements. I really don’t want to see ANY goto statements but I am not completely anal about it and realize that sometimes, very rarely, a goto is the best way to solve a logical flow issue in your code. This would kill my early structured programming instructors I had who would pass out if they even started to think someone was considering a goto.
  • The use of the starting curly brace “{” after an if, for, while, do, or something else where the curly brace is on the same line as the keyword UNLESS the end curly brace “}” is also on the same line. An example of what I don’t like here is when you see if (something) { and then several lines of code and then an end brace on its own line. It is ok, IMO if you see something like if (something) {do something}; though it is better written if (something) do something; though if you were writing in perl which follows a similar layout as c++ you must do the first so I got used to it… There really is nothing wrong with it, it just bothers me from a readabilty standpoint. I like blocks of code to be visibly blocked off and I think putting the start and end curly braces on their own lines helps that readability immensely; but then, I use a lot of whitespace when I write because I don’t like all of the statements bunched up on top of each other. I admit, since getting access to the MSFT source code this doesn’t bother me AS much as it used to because they always seem to do it but I still refuse to let any code I control use that format.
  • Excessive function call depth. This is when you keep breaking up what is done into smaller and smaller pieces so that in order to do some operation you have to dive through several levels of functions to actually get something done. While smaller functions are easier to debug, digging through a zillion levels of calls to be able to debug that small function is a bit silly. This one is a complete judgement call when you see it though. If you happen to see a function that has one simple line, there is a possibility that that function was watered down too much but maybe it makes sense to have been done that way… Note I am not ripping on recursion here, I like recursion.
  • And the thing that irks me that got me to sit down and write this entry… Not using iterators to iterate through STL containers…

Iterators were designed and built TO ITERATE THROUGH THE STL CONTAINERS. So why wouldn’t you try to use one? I don’t know, but there is a ton of code that I see where an STL Container is used and there is no attempt to use an iterator and that is the logical way, IMO, to handle it. It seems that a lot of folks who use the STL containers only use the containers and do not use STL iterators and STL algorithms. I think a lot of folks don’t know about or maybe don’t understand the iterators. While the containers are extremely cool, if you use them you should spend some time looking into using the iterators and algorithms as well as they are just as cool and make the containers that much more useful.

I bring this up because this morning I was reading Dr. Dobbs Journal (August 2006) and on page 53 there is an article called “In Defense of Laziness”. I am all about implementing laziness or being lazy in a constructive way, I think it is a great way to code… however, in the first examples I see

Note: Because wordpress has a wicked bad time with greater than and less than symbols I will write GT and LT to indicate them… 

for (int i=0; i LT vect.size();i++)
  // do whatever you need to do with i

I am being mean here because I don’t really know what the code is going to be doing and it is just to illustrate a point about writing code in a certain way but it puts out an example out there that may make people think it is the right way to do things with a vector. Rarely do you do something with i in a case like this example… You will most likely be doing something with vect or the values stored in vect and i will be used to iterate through vect. Anyway, the author goes on to point out that vect.size() might be slow and that this could really slow down the loop. I agree. His solution

const_int limit=vect.size();
for (int i=0; i LT limit; ++i)
  // do whatever you need to do with i

If you are actually doing something with i instead of with vect, this might be a good answer, but as he points out, you now have through a new variable (limit) out in program with a broader scope than it needed as it only really needs to exist for that one and only loop here. So the next example addresses that.

{
  const_int limit=vect.size();
  for (int i=0; i LT limit; ++i)
    // do whatever you need to do with i
}

A bit ugly but at least the braces are on lines of their own and if you are actually doing something with i instead of working with the values contained in vect, knock yourself out… However, if you are using the values in vect, you should almost certainly be using an interator. Depending on whether or not you want to change the values in vect will decide if you use a normal or constant iterator. Either way, an iterator is more elegant and probably one of the faster executing ways to do this. Alternately you can use the STL for_each algorithm which is also quiet cool.

I would say that a majority of my code that has to loop through some STL container for some reason looks like

for (containertype::const_iterator i=container.begin(); i != container.end(); i++)
 {
  // do whatever you had to do with the values in the container
 }

If I need to change the values I would probably use something like

for (containertype::iterator i=container.begin(); i != container.end(); i++)
 {
  // make changes to container values
 }

If using the STL for_each algorithm; it is tough to beat the elegance of

for_each(vect.begin(),vect.end(),dosomething());

  joe

 

Rating 3.00 out of 5

Comments are closed.

[joeware – never stop exploring… :) is proudly powered by WordPress.]