I've never implemented STL-like iterators and I try to understand how to implement a very basic thing based on pointers. Once I will have this class I will be able to modify it to do more complicated things. Consequently, this is a first step, and I need it to be rock solid to understand how to write my own iterators (without boost).
I have written the following code and I know that there are errors in it. Can you help me to design correctly a Random Access Iterator class inspired from that :
template<Type> class Container<Type>::Iterator : public std::iterator<random_access_iterator_tag, Type>
{
// Lifecycle:
public:
Iterator() : _ptr(nullptr) {;}
Iterator(Type* rhs) : _ptr(rhs) {;}
Iterator(const Iterator &rhs) : _ptr(rhs._ptr) {;}
// Operators : misc
public:
inline Iterator& operator=(Type* rhs) {_ptr = rhs; return *this;}
inline Iterator& operator=(const Iterator &rhs) {_ptr = rhs._ptr; return *this;}
inline Iterator& operator+=(const int& rhs) {_ptr += rhs; return *this;}
inline Iterator& operator-=(const int& rhs) {_ptr -= rhs; return *this;}
inline Type& operator*() {return *_ptr;}
inline Type* operator->() {return _ptr;}
inline Type& operator[](const int& rhs) {return _ptr[rhs];}
// Operators : arithmetic
public:
inline Iterator& operator++() {++_ptr; return *this;}
inline Iterator& operator--() {--_ptr; return *this;}
inline Iterator& operator++(int) {Iterator tmp(*this); ++_ptr; return tmp;}
inline Iterator& operator--(int) {Iterator tmp(*this); --_ptr; return tmp;}
inline Iterator operator+(const Iterator& rhs) {return Iterator(_ptr+rhs.ptr);}
inline Iterator operator-(const Iterator& rhs) {return Iterator(_ptr-rhs.ptr);}
inline Iterator operator+(const int& rhs) {return Iterator(_ptr+rhs);}
inline Iterator operator-(const int& rhs) {return Iterator(_ptr-rhs);}
friend inline Iterator operator+(const int& lhs, const Iterator& rhs) {return Iterator(lhs+_ptr);}
friend inline Iterator operator-(const int& lhs, const Iterator& rhs) {return Iterator(lhs-_ptr);}
// Operators : comparison
public:
inline bool operator==(const Iterator& rhs) {return _ptr == rhs._ptr;}
inline bool operator!=(const Iterator& rhs) {return _ptr != rhs._ptr;}
inline bool operator>(const Iterator& rhs) {return _ptr > rhs._ptr;}
inline bool operator<(const Iterator& rhs) {return _ptr < rhs._ptr;}
inline bool operator>=(const Iterator& rhs) {return _ptr >= rhs._ptr;}
inline bool operator<=(const Iterator& rhs) {return _ptr <= rhs._ptr;}
// Data members
protected:
Type* _ptr;
};
Thank you very much.
Your code has the following issues:
Iterator(Type* rhs)
could be private and the Container
could be marked as Iterator
's friend, but that's not strictly necessary.operator=(Type* rhs)
is a bad idea. That's not what type safety is about.Iterator
, not Iterator &
.std::iterator<std::random_access_iterator_tag, Type>::difference_type
instead of const int &
.const
.Useful resource: RandomAccessIterator @ cppreference.com
Here is a fixed version of your code:
template<typename Type>
class Container<Type>::Iterator : public std::iterator<std::random_access_iterator_tag, Type>
{
public:
using difference_type = typename std::iterator<std::random_access_iterator_tag, Type>::difference_type;
Iterator() : _ptr(nullptr) {}
Iterator(Type* rhs) : _ptr(rhs) {}
Iterator(const Iterator &rhs) : _ptr(rhs._ptr) {}
/* inline Iterator& operator=(Type* rhs) {_ptr = rhs; return *this;} */
/* inline Iterator& operator=(const Iterator &rhs) {_ptr = rhs._ptr; return *this;} */
inline Iterator& operator+=(difference_type rhs) {_ptr += rhs; return *this;}
inline Iterator& operator-=(difference_type rhs) {_ptr -= rhs; return *this;}
inline Type& operator*() const {return *_ptr;}
inline Type* operator->() const {return _ptr;}
inline Type& operator[](difference_type rhs) const {return _ptr[rhs];}
inline Iterator& operator++() {++_ptr; return *this;}
inline Iterator& operator--() {--_ptr; return *this;}
inline Iterator operator++(int) const {Iterator tmp(*this); ++_ptr; return tmp;}
inline Iterator operator--(int) const {Iterator tmp(*this); --_ptr; return tmp;}
/* inline Iterator operator+(const Iterator& rhs) {return Iterator(_ptr+rhs.ptr);} */
inline difference_type operator-(const Iterator& rhs) const {return _ptr-rhs.ptr;}
inline Iterator operator+(difference_type rhs) const {return Iterator(_ptr+rhs);}
inline Iterator operator-(difference_type rhs) const {return Iterator(_ptr-rhs);}
friend inline Iterator operator+(difference_type lhs, const Iterator& rhs) {return Iterator(lhs+rhs._ptr);}
friend inline Iterator operator-(difference_type lhs, const Iterator& rhs) {return Iterator(lhs-rhs._ptr);}
inline bool operator==(const Iterator& rhs) const {return _ptr == rhs._ptr;}
inline bool operator!=(const Iterator& rhs) const {return _ptr != rhs._ptr;}
inline bool operator>(const Iterator& rhs) const {return _ptr > rhs._ptr;}
inline bool operator<(const Iterator& rhs) const {return _ptr < rhs._ptr;}
inline bool operator>=(const Iterator& rhs) const {return _ptr >= rhs._ptr;}
inline bool operator<=(const Iterator& rhs) const {return _ptr <= rhs._ptr;}
private:
Type* _ptr;
};
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