What's the difference between const_iterator<T> and iterator<const T>?

Viewed 686

Let's say I'm implementing a collection, say something like std::vector. I need to implement iterator and const_iterator, but once I've made iterator can const_iterator not just be implemented as iterator<const T> (where T is the type contained in the collection)?

There must be some reason why this doesn't work because there are a million questions about how to re-use code while implementing iterator and const_iterator but none of them say "just use const T as the type".

1 Answers

std::iterator_traits<Iter>::value_type should be T for const_iterator<T>, but const T1 for iterator<const T>. If you use iterator<const T> as const_iterator<T>, you would have to violate one of these assumptions.

It should possible to use a common template for both iterators as long as constness of the value type is a separate template argument from constness of the iterator. Something like:

template<class T>
struct container
{
    template<class ItPtr>
    struct iterator_common
    {
        using value_type = T;
        using pointer = ItPtr;
        using reference = std::remove_pointer_t<ItPtr>&;
        // ...
    };

    using iterator = iterator_common<T*>;
    using const_iterator = iterator_common<const T*>;
    // ...
};

1 Until C++20, in which it should be std::remove_cv_t<const T> which is T. As such, this won't be a problem to your suggestion in the future standard version.

Related