I feel like I'm unprofessional in the way I name and use iterators. What I mean by that is that I "feel" like I should be calling them something else, but I always name them based on the "it_" prefix, and after a while, in a long function, the names start to all look alike.
Additionally, I always wonder if I'm doing things a "strange" way that I learned just because I didn't know better. For instance, if I were iterating through a map to display all its key/value pairs, I would do this:
map<int, int>::const_iterator it = layout.begin(); for (; it != layout.end(); ++it) { cout << it->first << ":\t" << it->second << "\n"; }
I see some people calling their iterators "iter" - I see other ways of doing loops. Is there any kind of convention that transcends style and is just good practice?
I haven't seen a single canonical loop.
The cost of creating an iterator
is specified to be O(1)
(wrt the size of the container), but it may cost, especially when specific debugging options are activated.
Therefore, calling end
at each iteration of the loop is wasteful.
The canonical way to write a for
loop is therefore to compute both it
and end
in the first statement.
typedef std::map<int,int> LayoutType;
for (LayoutType::const_iterator it = layout.begin(), end = layout.end();
it != end; ++it)
{
// ...
}
I usually typedef my container, but honestly there isn't much point in typedefing the iterator, it's already available within the container and introducing too many synonyms does not help.
Also, it may be a personal quirk, but I prefer stating the function rather than the type when I introduce my typedef. The type may change in later refactoring, the function will not (at least, it won't be the same thing at all if it does, so it'll call for a complete rewrite).
For example what if you suddenly preferred: typedef std::unordered_map<int,int> LayoutType
? It still matches your need, and you can probably drop it in at no rewriting cost (providing you have used a typedef).
I try to declare the iterators inside the for
loop as much as possible, so that the scope of the iterator identifier is minimized.
First, I typedef
the "long" type names to "shorter" and re-usable ones:
typedef std::map< int, int > IntMap;
typedef IntMap::const_iterator IntMapConstIter;
Then, I do
for( IntMapConstIter it = layout.begin(); it != layout.end(); ++it ) {
....
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With