Questions about Getting const_iterator out of iterator class

C

CoolPint

If I were to design my own container and its iterators, I understand
that I need to provide both "iterator" and "const_iterator" so that
begin() and end() return appropriate ones depending on the
"constantness" of the container object. I also note that is it done
through overloading begin() and end() like below:

iterator begin();
const_iterator begin() const;

So it seems to me that I need to have two separate iterator classes
which are very similar except that const_iterator's operator*()
returns const reference. I also need to provide conversion from
iterator to const_iterator (probably by overloading copy constructor
of const_iterator class to accept iterator class objects) so that
iterator objects can be assigned to const_iterator objects.
Or I could use inheritance to derive iterator from const_iterator.

I hope my understanding so far is correct up to now.

Can I achieve the same effect by doing something like below rather
than having two different classes which are almost identical?

template <typename T>
class Container {
public:
class ContainerIterator;
typedef ContainerIterator iterator;
typedef const ContainerIterator const_iterator;
// other member functions

iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
private:
// private members
};

template <tyename T>
class Container<T>::ContainerIterator {
friend class Container<T>;
public:
ContainerIterator();
T & operator*();
const T & operator* () const; // so that const_iterator can be
deferenced
iterator & operator++();
const_iterator & operator++() const; // so that const_iterator can
be moved
iterator operator++(int);
const_iterator operator++(int) const;
iterator & operator--();
const_iterator & operator--() const;
iterator operator--(int);
const_iterator operator--(int) const;
bool operator==(const ListIterator &) const;
bool operator!=(const ListIterator &) const;
private:
// private members
};

I would appreciate any comment on whether this would be a viable
alternative or if not, what kind problems this might create. Thank you
in advance.
 
R

Ron Natalie

I would appreciate any comment on whether this would be a viable
alternative or if not, what kind problems this might create. Thank you
in advance.

If I understand you correctly, you want to use a common iterator class
for both const_iterator and iterator and use the constness of that iterator
to determine whether the iterator points to a const object.

This won't work very well, because all someone has to do is copy the
iterator
and it will lose track of whether it needs to be const or not.

const Container cont;
Container::iterator it = cont.begin(); // Now have an non-const iterator
to const object
 
O

Olaf Lenzmann

If I were to design my own container and its iterators, I understand
that I need to provide both "iterator" and "const_iterator" so that
begin() and end() return appropriate ones depending on the
"constantness" of the container object. I also note that is it done
through overloading begin() and end() like below:

iterator begin();
const_iterator begin() const;

So it seems to me that I need to have two separate iterator classes
which are very similar except that const_iterator's operator*()
returns const reference. I also need to provide conversion from
iterator to const_iterator (probably by overloading copy constructor
of const_iterator class to accept iterator class objects) so that
iterator objects can be assigned to const_iterator objects.
Or I could use inheritance to derive iterator from const_iterator.

I hope my understanding so far is correct up to now.

Can I achieve the same effect by doing something like below rather
than having two different classes which are almost identical?

template <typename T>
class Container {
public:
class ContainerIterator;
typedef ContainerIterator iterator;
typedef const ContainerIterator const_iterator;
// other member functions

iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
private:
// private members
};

template <tyename T>
class Container<T>::ContainerIterator {
friend class Container<T>;
public:
ContainerIterator();
T & operator*();
const T & operator* () const; // so that const_iterator can be
deferenced
iterator & operator++();
const_iterator & operator++() const; // so that const_iterator can
be moved
iterator operator++(int);
const_iterator operator++(int) const;
iterator & operator--();
const_iterator & operator--() const;
iterator operator--(int);
const_iterator operator--(int) const;
bool operator==(const ListIterator &) const;
bool operator!=(const ListIterator &) const;
private:
// private members
};

I would appreciate any comment on whether this would be a viable
alternative or if not, what kind problems this might create. Thank you
in advance.

You are mixing semantics of const: a const_iterator is meant to refer
to something const, it is not a const object itself. How can you
implement

const_iterator & operator++() const;

without violating the const modifier on the function? Advancing the
iterator surely does change the iterator object.

Olaf
 
C

CoolPint

If I understand you correctly, you want to use a common iterator class
for both const_iterator and iterator and use the constness of that iterator
to determine whether the iterator points to a const object.

Spot on! That's what I was hoping to achieve and now I understand it
won't work as you point out.
This won't work very well, because all someone has to do is copy the
iterator
and it will lose track of whether it needs to be const or not.

const Container cont;
Container::iterator it = cont.begin(); // Now have an non-const iterator
to const object

Thanks for pointing this out! I also learned that assigning iterator
objects to const_iterator objects are impossible since const_iterator
is
const IteratorClass!
And then I would not be able to have const const_iterator either,
wouldn't I?

Silly me!

So is having separate classes for iterator and const_iterator only
solution in this case?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top