“It was one of my most brilliant ideas, and between you and me, that’s saying something….My brain surprises even me sometimes…”
Albus Dumbledore – Harry Potter and The Philosopher’s Stone
What should this quote be doing here. Well I had a similar idea 30 minutes ago, out of which it took 15 minutes to write this post and get the two references. You see, in C++, iterators are a core concept related to streams and container. They may get redesigned a bit in near future (or may already have) but the notion will not change.
At the beginning, there was one, the input_iterator. It can only go forward and be dereferenced only once. Then came, the forward_iterator, it can also only go forward but can be dereferenced multiple times. This evolved into bidirectional_iterator, which can move in either direction and is a forward_iterator. Finally, the chain terminates at random_access_iterator which allows random access, chiefly [ ] and +, -, in addition to being a bidirectional_iterator.
With this background, I was writing a class which needed distinguished behavior depending upon the iterator type specified as a template argument. I thought, and kept thinking about it as to how should I approach the problem. I had already said a big “no” to partially specializing it, or any of the base classes, upon iterator type.
Therefore, the distinguishable functionality now resides in a separate class. I decided not to support input_iterator. Hierarchy starts at forward_iterator and goes hands in hands with other three.
Sorry about the cryptic text, that’s the spirit of C++ I like most.
template< typename iter , typename projection , typename category = std::forward_iterator_tag > class projection_iterator : public std::iterator< category , projection , typename std::iterator_traits< iter >::difference_type , typename std::iterator_traits< iter >::pointer , typename std::iterator_traits< iter >::reference >
// things like ++ (pre,post), *, ->, == and !=.
// This gets rid of input_iterator. Any attempts to instantiate will result in compile time error of type not defined.
template< typename iter , typename projection > class projection_iterator< iter , projection , std::input_iterator_tag >;
template< typename iter , typename projection > class projection_iterator< iter , projection , std::bidirectional_iterator_tag > : public projection_iterator< iter , projection , std::forward_iterator_tag >
// inherits from general class, adds — (pre,post).
template< typename iter , typename projection > class projection_iterator< iter , projection , std::random_access_iterator_tag > : public projection_iterator< iter , projection , std::bidirectional_iterator_tag >
// inherits from bidirectional_iterator case, adds [ ], +, -.
With implementation inheritance, I have reduced the amount of code I would have written otherwise quite drastically.
It is still a work in progress. I, most specifically, don’t want any comment from you or bugging me on IM.