Search code examples
c++design-patternsiteratorconst-iterator

Should the regular iterator (or a similar range / view class) derive from const_iterator?


Is it a good practice to make the regular iterator (or a similar range or view class) derive from the corresponding const_iterator?

The motivation for this is

  • sharing the code, and
  • avoiding conversions, when the iterator / view is big.

As an example, consider a view of a 3D grid, i.e. a section of the grid. It may contain 1 pointer, 3 sizes and 2-3 strides, for a total of 384 bytes.

The const and mutating versions would have a lot of common functionality (anything you can do with a read-only 3D grid).

The anti-motivation for the above example is that the const view contains a const pointer, and so the mutating view would have to do a const_cast to use it, or add an extra field containing the same address in a non-const pointer.


Solution

  • If there is inheritance between const_iterator and iterator it should probably go the other way. That is a const iterator provides the basic ability to navigate and the mutable iterator adds the ability to modify the target (implemented by allowing protected access to const_iterator internals).

    Edit: the original question asked about deriving const_iterator from iterator. That is a bad idea as both I and @David Rodriguez pointed out at almost exactly the same time.

    With the revised question, deriving iterator from const_iterator, David's comment provides the best response. It can be done but it's usually not a good idea.

    As a counter-question: what advantage do you see in using inheritance for this case? If there is an advantage, does having a common base class (iterator_impl) from which both iterator and const_iterator are derived provide the same advantage?