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).
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With