Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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".

like image 419
BeeOnRope Avatar asked Jun 17 '19 01:06

BeeOnRope


People also ask

What is const iterator?

A const iterator points to an element of constant type which means the element which is being pointed to by a const_iterator can't be modified. Though we can still update the iterator (i.e., the iterator can be incremented or decremented but the element it points to can not be changed).

What is the difference between Begin and Cbegin?

begin() returns an iterator to beginning while cbegin() returns a const_iterator to beginning. The basic difference between these two is iterator (i.e begin() ) lets you change the value of the object it is pointing to and const_iterator will not let you change the value of the object.

What is iterator in C++?

An iterator is an object that can iterate over elements in a C++ Standard Library container and provide access to individual elements.

What is an iterator in vector?

Vector's iterators are random access iterators which means they look and feel like plain pointers. You can access the nth element by adding n to the iterator returned from the container's begin() method, or you can use operator [] . std::vector<int> vec(10); std::vector<int>::iterator it = vec.


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.

like image 154
eerorika Avatar answered Oct 07 '22 11:10

eerorika