Code for a basic random access iterator based on pointers?

后端 未结 3 1104
醉梦人生
醉梦人生 2020-12-28 20:35

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 modif

相关标签:
3条回答
  • 2020-12-28 20:56

    In general your approach is right. The postfix increment/decrement operator should return by value, not by reference. I also have doubts about:

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

    This tells everyone that this iterator class is implemented around pointers. I would try making this method only callable by the container. Same for assignment to a pointer. Adding two iterators makes no sense to me (I would leave "iterator+int"). Substracting two iterators pointing to the same container might make some sense.

    0 讨论(0)
  • 2020-12-28 21:01

    Have a look at how Boost do it, the iterators in boost/container/vector.hpp - vector_const_iterator and vector_iterator are reasonably easy to understand pointer based iterators.

    0 讨论(0)
  • 2020-12-28 21:08

    Your code has the following issues:

    • You do not follow the Rule of Three/Five. The best option in your situation is not to declare any custom destructors, copy/move constructors or copy/move assignment operators. Let's follow so called Rule of Zero.
    • 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.
    • Post-in(de)crementation should return Iterator, not Iterator &.
    • Adding two iterators has no meaning.
    • Subtracting two iterators should return a difference, not a new iterator.
    • You should use std::iterator<std::random_access_iterator_tag, Type>::difference_type instead of const int &.
    • If a method does not modify an object, it should 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;
    };
    
    0 讨论(0)
提交回复
热议问题