Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ iterators considered harmful?

People also ask

What is iterators in C?

An iterator is an object that allows you to step through the contents of another object, by providing convenient operations for getting the first element, testing when you are done, and getting the next element if you are not. In C, we try to design iterators to have operations that fit well in the top of a for loop.

Can iterators be compared C++?

we can use == and != to compare to valid iterators into any of the library containers. The section also tells us that iterators for string and vector support relational operators (aka iterator arithmetic) which include >, >=, <, <=.

Should iterators be passed by value or reference?

In general: If you pass a non- const reference, the caller doesn't know if the iterator is being modified. You could pass a const reference, but usually iterators are small enough that it gives no advantage over passing by value.

Why are iterators useful C++?

Use of Iterators in C++ An iterator in C++ serves the following major purposes: The primary objective of an iterator is to access the STL container elements and perform certain operations on them. The internal structure of a container does not matter, since the iterators provide common usage for all of them.


First, to answer your questions:

  1. No. In fact, I argued elsewhere that iterators are the most important/fundamental concept of computer science ever. I (unlike Andrei) also think that iterators are intuitive.
  2. Yes, definitely but that shouldn't come as a surprise.
  3. Hmm. Looking at Boost.Range and C++0x – haven't they already?

Andrei's big contribution here is just to say: drop the concept of iterators altogether, see ranges not just as a convenience wrapper but rather as a core construct. Other languages have already done this (much of Andrei's concepts just echo .NET's LINQ or Python's iterators) but they all only offer output ranges. Andrei argues for different types of ranges, much like the conventional iterator categories.

In that light, it's odd that he starts by mocking the arbitrariness of these iterator categories.

I also think that his examples are off, especially his file copying: yes, the iterator variant is a huge improvement over the 1975 code. It reduces a loop with complicated break condition down to one statement. What he's really taking issue with here is just the syntax. Well, excuse me: we're talking about C++ here – of course the syntax is ugly. And yes, using ranges here is an improvement – but only syntactically.

I also think that Andrei's find implementation is off. What he really defines there is the DropUntil operation (naming is hard!) from LINQ. The find operation should really return either one or zero elements (or an iterator!). Shunning iterators here isn't helpful in my opinion since we might want to modify the value directly instead of copying it. Returning a one-element range here only adds overhead without a benefit. Doing it Andrei's way is bad because then the name of the method is just wrong and misleading.

That said, I essentially agree with Andrei in almost all points. Iterators, while being my pet concept from computer science, are certainly a big syntactical burden and many ranges (especially infinite generators) can (and should) be implemented conveniently without them.


I agree with him that iterators are mostly inferior to ranges, and I don't know if 'something better' will get picked up.

"The good is the enemy of the best" is strongly at play here, as it usually is. Iterators are useful and firmly entrenched, so it's hard to know if something better like ranges can supplant them in a reasonable amount of time.


  1. Most of us make a simple use of them in what have become well known idioms, like in for loops to iterate through an std::vector. A developer reads it and knows what's going on. In our everyday coding life, iterators are not good or bad, they're just "what gets the job done".
  2. Probably, yes.
  3. I don't think so.

Andrei at times can be a bit provocative. Iterators are a reasonable concept, and quite fundamental in the sense that bits are. But just like most bits in C++ are not bools, but part of larger types,most iterators should be dealt with at a high level. Andrei is right that the proper level to do so is the range object. But not all ranges are properly exposed as iterator ranges, as the istream_iterator sentinel shows. That's just a hack to create an artificial end iterator. I don't think his ideas will be picked up by implementations, though. C++1x will be as relevant as C99.


C++0x is already making the first steps:

  • rvalue references solve some problems with treating containers as ranges
  • ranges have been added to the core library, including range concepts

Transitioning to ranges without losing any iterator functionality (think of all the combinations of iterator categories, const-ness and rvalue-ness) is hard, especially if you try to factor in infinite and mutable ranges.