4

I am writing an iterator class (say MyIterator) for a library.

Is it a good idea to use const overloading to make const MyIterator acts like a const_iterator of std::vector while MyIterator acts as like iterator of std::vector ?

Will the library user/developer get confused?

The implementation would be like:

// std::iterator example
#include <iostream>     // std::cout
#include <iterator>     // std::iterator, std::input_iterator_tag

class MyIterator : public std::iterator<std::input_iterator_tag, int>
{
  mutable int* p;
public:
  MyIterator(int* x) :p(x) {}
  MyIterator(const MyIterator& mit) : p(mit.p) {}
  MyIterator& operator++() {++p;return *this;}
  MyIterator operator++(int) {MyIterator tmp(*this); operator++(); return tmp;}
  bool operator==(const MyIterator& rhs) {return p==rhs.p;}
  bool operator!=(const MyIterator& rhs) {return p!=rhs.p;}
  const int& operator*() const {return *p;} // <-- const overload
  int& operator*() {return *p;}
};

An alternative would be using templates to implement a single iterator class that can be specialized into the const and non-const iterators. I am currently doing that (i heard boost is doing that...). But, the templates get complex very quickly as I implement range, and then range of range (as in nested range based for loop).

dot dot dot
  • 231
  • 1
  • 9
  • 1
    The hell is a `mit`? Might answer your question. – George Nov 04 '16 at 17:25
  • 1
    @George I take it as the iterator is called `mit`. Possibly shorthand for `my_iterator`. – NathanOliver Nov 04 '16 at 17:27
  • I would get confused, but that's just me. – jrok Nov 04 '16 at 17:28
  • 3
    Not clear to me what you are asking, but a `const_iterator` is an iterator that points to a const thing, while a `const` iterator is an iterator that cannot be made to point to something else. – Benjamin Lindley Nov 04 '16 at 17:32
  • 1
    A `const iterator` and a `const_iterator` are logically different and I would recommend you don't confuse those semantics. But I am not sure from your question if or how you mean to do that. – Galik Nov 04 '16 at 17:37

1 Answers1

8

Using const MyIterator as a substitute of const_MyIterator (const_iterator) won't work, because const_iterator is not meant to be a constant iterator, but an iterator iterating over constant elements.

Also, with a const MyIterator, you couldn't use modifying operators, like ++ or --, because these are non-const methods, modifying the iterator itself.

So, if you want to provide some sort of const_iterator, you won't get around implementing one.

Will the library user/developer get confused?

Finally, to answer your question: Yes, I think so, because of the different behaviour (and expectations) of a const iterator vs const_iterator.

Olaf Dietsche
  • 72,253
  • 8
  • 102
  • 198
  • it can work. just need to define which attribute as mutable when I implement the iterator. I am not sure if that is a good idea though. – dot dot dot Nov 04 '16 at 17:43
  • @dotdotdot no it's absolutely *not* a good idea. Just because something is possible does not mean you should do it. – Mark Ransom Nov 04 '16 at 17:46
  • Yes, you're right, it is possible technically. But it would add to the confusion and violate the expectation of the behaviour of a `const` object. – Olaf Dietsche Nov 04 '16 at 17:47
  • Is doing this for a range acceptable? The 50+ upvote answer at http://stackoverflow.com/questions/148540/creating-my-own-iterators?rq=1 by Konrad Rudolph is doing that. – dot dot dot Nov 04 '16 at 18:28
  • This is different, because both `const_iterator begin() const` and `end()` don't modify the `Piece` object. They create a new object (const_iterator), or obtain it from `m_shape`, and return this. – Olaf Dietsche Nov 04 '16 at 19:41