Code for a pointer-based random random access iterator?

I have never used STL-like iterators, and I am trying to figure out how to implement a very basic thing based on pointers. Once I have this class, I can change it to do more complex things. Therefore, this is the first step, and I need it to be strong in order to understand how to write your own iterators (without promotion).

I wrote the following code, and I know that it has errors. Can you help me design the random access Iterator class correctly, inspired by this:

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.

+4
source share
3 answers

In general, your approach is right. The postfix increment / decment statement should be returned by value , not by reference. I also have doubts:

 Iterator(Type* rhs) : _ptr(rhs) {;} 

This tells everyone that this iterator class is implemented around pointers. I would try to make this method only called container. The same goes for assignment to a pointer. Adding two iterators makes no sense to me (I would leave iterator + int). Selecting two iterators pointing to the same container may make sense.

0
source

Your code has the following problems:

  • You do not follow the Three / Five rules. The best option in your situation is not to declare any arbitrary destructors, copy / move constructors, or copy / move destination statements. Let me follow the so-called Rule of Zero.
  • Iterator(Type* rhs) may be private, and Container may be marked as Iterator friend, but this is not necessary.
  • operator=(Type* rhs) is a bad idea. This is not the type of security.
  • Post-in (de) Iterator should return an Iterator , not an Iterator & .
  • Adding two iterators does not make sense.
  • Subtracting two iterators should return the difference, not a new iterator.
  • You should use std::iterator<std::random_access_iterator_tag, Type>::difference_type instead of const int & .
  • If the method does not modify the object, it must be marked 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 Iterator(_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; }; 
+4
source

See how Boost does this; iterators in boost / container / vector.hpp - vector_const_iterator and vector_iterator fairly easy to understand pointer based iterators.

+1
source

All Articles