简体   繁体   中英

What is the difference between STL containers iterator and C pointer iterator

i am writing a reverse iterator as a part of my own custom vector class. Up till now what i have written is as following.

class MyVector
{
  public:

  typedef T                           value_type;
  typedef value_type*                 pointer;
  typedef const value_type*           const_pointer;
  typedef value_type&                 reference;
  typedef const value_type&           const_reference;
  typedef pointer                     iterator;
  typedef const_pointer               const_iterator;
  typedef size_t                      size_type;

    class reverse_iterator
    {
        private:

        iterator iter;

        public:

        inline reverse_iterator(iterator a=0) : iter(a) {}
        inline reverse_iterator(const reverse_iterator& rev_iter) : iter(rev_iter.iter) {}
        inline reverse_iterator& operator++()
        {
            --iter;
            return *this;
        }
        // and remaining other operator functions
    };

  inline iterator begin (void) { return ((iterator)data_array);           }
  inline iterator end (void)   { return ((iterator)data_array+number_of_elements); }
  inline reverse_iterator      rbegin(void)    { return end()-1;}
  inline reverse_iterator      rend(void)      { return begin()-1;}


    //functions for myvector class 
}; //end of Myvector class

in above class iterater is just C style pointer and reverse_iterator is class. So when i do

    main()
    {
        myVector<int> i;
        myVector<int>::reverse_iterator rit= i.begin();
    }

my reverse_iterator is initialised with begin() function and code is compiling and running. But this does not happen in case of STL's iterator and reverse_iterator. They prevent such initialisation. eg reverse_iterator not allow himself to be initialised with begin() function, it must be initialised with rbegin() .

So what should i do to avoid such kind of initialization ?. Should i write a different iterator like which is in STL. And i think it is not possible to write it.. Please give me some solution...

Iterators and reverse iterators have a few differences.

The most obvious: incrementing each iterator moves them in opposite directions.

Less obvious: the return of begin() is not the end of a reverse iterator. begin()-1 would be. Remember that end() represents "one-past-the-end", as C++ ranges are half open, ie [begin, end). If you just swap begin() and end() in your reverse iterator then your reverse iterator will have the range (begin, end].

In other words, there's a reason why STL containers have both begin() and end() and rbegin() and rend() , even if the iterators and reverse iterators themselves might be compatible in some ways.

To completely prevent conversion from iterator (pointer) to reverse_iterator , make the constructor of reverse_iterator private, and make MyVector a friend of reverse_iterator :

class MyVector
{
  // ...
  class reverse_iterator
  {
  private:
    friend class MyVector;
    reverse_iterator(iterator a=0) : iter(a) {}
    // ...
  };
  // ...
};

If you want that conversion available, but not automatic, then just make the corresponding constructor explicit .

class MyVector
{
  // ...
  class reverse_iterator
  {
  public:
    explicit reverse_iterator(iterator a=0) : iter(a) {}
    // ...
  };
  // ...
};

In an unrelated note, I also notice that your implementation of rbegin() probably invokes undefined behaviour (I can't tell for sure because it depends on the code initializing data_array ): You are not allowed to decrement the pointer to the beginning of an array.

By the way, the keyword inline is not necessary in your case; if you write the member function body inside the class definition, it is automatically inline. Of course, the inline doesn't hurt either.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM