views:

156

answers:

3

After another question about iterators I'm having some doubts about custom containers. In my container, iterator is a subclass of const_iterator, so that I get conversion from non-const to const "for free". But is this allowed or are there any drawbacks or non-working scenarios for such a setup?

A: 

Think about a case which will require you to modify the iterator's members.

rursw1
And? I guess you need to elaborate.
doublep
+3  A: 

Yes, this is fine. This is how VC10's implementation of the iterators for vector are structured, for example. See _Vector_iterator and _Vector_const_iterator in <vector>.

By the way, writing iterators is hard. It's worth your time to learn and use the boost::iterator library.

Terry Mahaffey
I know, but in my case it's a small library and I don't want it to depend on anything, including Boost parts.
doublep
It's already good that some implementation of STL works like that. Do you happen to know a clause in the standard that describes iterators and requirements in general?
doublep
24.2 of the FCD (n3035.pdf) describes iterators and their requirements
Terry Mahaffey
Thanks. Let's wait if more opinions appear.
doublep
A: 

Subclassing seems strange to me here, but there is effectively an issue.

Even if you don't want to depend on Boost parts, check the Boost.Iterator library, and more especially the iterator_facade and iterator_adaptor bits.

There is a full-blown example of how to write an iterator and a const_iterator for your class without duplicating too much. Their idea is to write a template iterator_base class which you can then use for const and non-const types in the line of:

template <class Value> class iterator_base;

typedef iterator_base<T> iterator;
typedef iterator_base<const T> const_iterator;

The issue with subclassing is that you should then provide a virtual destructor and you're exposed to slicing (when building a const_iterator from an iterator)

So, unlike others here, I don't find it "fine".

Matthieu M.
"You should then provide a virtual destructor" — but my destructors don't do anything anyway. Even if they did, `iterator` type would probably just inherit `const_iterator` destructor, without doing anything extra. "you're exposed to slicing" — can you please elaborate, I don't understand what you mean here.
doublep