1.11M Members

Need help writing my own reverse iterator class

 
0
 

I have a hw project and I need to write my own reverse iterator. The problem is i don't know for sure if I'm starting off ok. Here is the code I have so far and a simple test in main keeps giving me an error stating no parameter's for template if I initialize like so:

main() {
vector<int> v;
vector<int>::iterator it;
my_reverse_iterator p(it);
}

BUT when i initialize differently i get errors such as:

main() {
vector<int> v;
vector<int>::iterator it;
my_reverse_iterator <vector<int> > p(it);
}

it gives me a bunch of errors stating:
Anachronism: using iterator_traits as a template without a declaration.
ERROR: iterator_traits is not defined.

Here is the code I have so far:

#include<iostream>
#include<iterator>
#include<vector>

using namespace std;

template <class Iter>
class my_reverse_iterator/*:public iterator<
    typename iterator_traits<Iter>::iterator_category,
    typename iterator_traits<Iter>::value_type,
    typename iterator_traits<Iter>::difference_type, 
    typename iterator_traits<Iter>::pointer,
    typename iterator_traits<Iter>::reference>
*/
{
    private:
         Iter p;
    public:

        typedef typename iterator_traits<Iter>::iterator_category iter_cat;
        typedef typename iterator_traits<Iter>::value_type val_type;
        typedef typename iterator_traits<Iter>::difference_type diff_type;
        typedef typename iterator_traits<Iter>::pointer ptr;
        typedef typename iterator_traits<Iter>::reference ref;

    public:
        typedef Iter iterator_type;
        typedef my_reverse_iterator<Iter> self;

        my_reverse_iterator() {} 

        explicit my_reverse_iterator(iterator_type i):p(i) {}
/*
        ~my_reverse_iterator() {}
        .... base() { return p; }
        // prefix
        .... operator++()
        {
            --p;
            return *this;
        } 

        // postfix
        .... operator++(int i)
        {

        }
        // prefix
        .... operator--()
        {
            ++p;
            return *this;
        }
        
        // postfix
        .... operator--(int i)
        {
        
        }
        
        // binary +
        .... operator+(int i)
        {
            for ( int j = 0; j < i; j++)
                --p;
            return *this;
        }
        
        // binary -
        .... operator-(int i)
        {
            for ( int j = 0; j < i; j++)
                ++p;
            return *this;
        }
        
        // +=
        .... operator+=(int i)
        {
            
        }
        
        // -=
        ....operator-=(int i)
        {

        }
        
        //  *
        typename iterator_traits<Iter>::value_type operator*() { return *p; }

        // ->
        typename iterator_traits<Iter>::value_type operator->()
        {
            return ;
        }
        
        // []
        .... operator[]()
        {

        }
*/
};

main()
{
    vector<int> v;
    vector<int>::iterator it;
//    it = v.begin();
    my_reverse_iterator<vector<int> > p(it);
}

What am I doing wrong??

Thanks In Advance,

 
0
 
main() {
vector<int> v;
vector<int>::iterator it;
my_reverse_iterator p(it);
}

In this case the problem is clear, you're trying to create an object of a type that's not complete. You need to first create the type by instantiating the template (using template args), only then you can create an object of this type.

main() {
vector<int> v;
vector<int>::iterator it;
my_reverse_iterator <vector<int> > p(it);
}

In this case you are getting errors because you've not copied the complete implementation of reverse_iterator. :).
To explain the error
1. you need to include the file that has iterator_traits defined.
2. your c'tor takes iterator_type you're giving it iterator_type* .
2. once you correct this you should get more errors.

Basic problem is you've copied the code of something that is meant to a compiler independent, container independent, extensible (in terms of relations between different iterator classes) implementation. You need to copy a lot more to make it work.

Suggestion:
Forget/dump what the "really good fundoo STL developers" have implemented. Start from scratch and implement exactly and only what you need.
Never copy code that you don't understand. Instead readup and try to write yourself, once you get stuck in some specific problem refer to the code you would've wanted to copy, to see how they solved that problem.
If you have already implemented iterator you would know the simple fact of life abt iterators is that it's a class hiding a pointer.

 
0
 

Thank you for your detailed explanation. That was the most in depth answer I have received so far, and hopefully not the last.

I actually DO want to start from scratch as you suggested, but I don't seem to know how. The code I included in my post IS my attempt at starting from scratch, albeit partially copying someone's code.

As of right now, I really am only looking to get the ball rolling. I'm looking to create a reverse_iterator_class with a default constructor and a constructor that takes an iterator. And test these two in main. from there i'm sure I'll have more questions, but at least I can't get the framework put in.

Here's the code we started with:

#include<iostream>
#include<iterator>
#include<vector>

using namespace std;

template <class Iter>
class my_reverse_iterator : public iterator<
    typename iterator_traits<Iter>::iterator_category,
    typename iterator_traits<Iter>::value_type,
    typename iterator_traits<Iter>::difference_type, 
    typename iterator_traits<Iter>::pointer,
    typename iterator_traits<Iter>::reference>
{
    private:
         Iter p;
    public:
        my_reverse_iterator() {}
    my_reverse_iterator(Iter i):p(i) {}
};


main() {
vector<int> v;
vector<int>::iterator it;
my_reverse_iterator p(it);
}

Compiling this i get the following errors:
"my_reverse_iterator.cpp", line 27: Error: No parameters provided for template.
"my_reverse_iterator.cpp", line 27: Error: Cannot use int* to initialize int.

Thank You

 
0
 

you are getting the error here.

my_reverse_iterator p(it);

this is because my_reverse_iterator is a template class; you are not using it as such.
change that to

my_reverse_iterator<vector<int>::iterator> p(it);

and you can get started on the rest of the class.

i presume you are not allowed to use the iterator adapter provided by libstdc++; if you are you could get your reverse iterator by a mere typedef. for example:

#include <iterator>
#include <iostream>
#include <algorithm>
using namespace std ;

int main()
{
  char cstr[] = "abcdefghijkl" ;
  
  typedef  char* iterator ;
  iterator begin(cstr), end(cstr+sizeof(cstr)-1) ; // exclude the null
  copy( begin, end, ostream_iterator<char>(cout) ) ; cout << '\n' ;

  typedef reverse_iterator<iterator>  rev_iterator ;
  rev_iterator rbegin(end), rend(begin) ;
  copy( rbegin, rend, ostream_iterator<char>(cout) ) ; cout << '\n' ;

  typedef reverse_iterator<rev_iterator>  rev_rev_iterator ;
  rev_rev_iterator rrbegin(rend), rrend(rbegin) ;
  copy( rrbegin, rrend, ostream_iterator<char>(cout) ) ; cout << '\n' ;
}
 
0
 

Making the changes suggested gave me the errors from before:
Anachronism: using iterator_traits as a template without a declaration.
ERROR: iterator_traits is not defined.

In researching this error, i found that i need to define it properly. There are two ways. "First, define your iterator so that it has nested types I::value_type, I::difference_type, and so on. Second, you can explicitly specialize iterator_traits for your type." - SGI.com

How do I do either and which is best for what I'm trying to do? where can I go to better understand either of these two methods? And is my research incorrect in that the solution is elsewhere?

Also, vijayan121, I can not us iterator adapters since I am making my own reverse_iterator class. Thank you for the suggestion though.

Thanks,

 
0
 

Making the changes suggested gave me the errors from before:
Anachronism: using iterator_traits as a template without a declaration.
ERROR: iterator_traits is not defined.

In researching this error, i found that i need to define it properly. There are two ways. "First, define your iterator so that it has nested types I::value_type, I::difference_type, and so on. Second, you can explicitly specialize iterator_traits for your type." - SGI.com

i tested the code (with the change my_reverse_iterator< vector<int>::iterator > p(it) ; ) on vc++ 8, gcc 3.4.6 and icc 9.1; in all of them it compiles without errors or warnings.
vector<T>::iterator is fully std library compliant; it works correctly with iterator_traits<>.

 
0
 

Unfortunately I don't know how to check what type of compiler I'm using although I do know I'm running in a Linux box. But the following code finally compiled for me. Seems I need to add the typedefs that didn't seem to inheret when i did it. Is this correct or does it work as a fluke?

#include<iostream>
#include<iterator>
#include<vector>

using namespace std;

  template <class Iter>
  struct iterator_traits {
    typedef typename Iterator::iterator_category iterator_category;
    typedef typename Iterator::value_type        value_type;
    typedef typename Iterator::difference_type   difference_type;
    typedef typename Iterator::pointer           pointer;
    typedef typename Iterator::reference         reference;
  };

  template <class T>
  struct iterator_traits<T*> {
    typedef random_access_iterator_tag iterator_category;
    typedef T                          value_type;
    typedef ptrdiff_t                  difference_type;
    typedef T*                         pointer;
    typedef T&                         reference;
  };



template <class Iter>
class my_reverse_iterator : public iterator<
    typename iterator_traits<Iter>::iterator_category,
    typename iterator_traits<Iter>::value_type,
    typename iterator_traits<Iter>::difference_type, 
    typename iterator_traits<Iter>::pointer,
    typename iterator_traits<Iter>::reference>

{
    private:
         Iter p;
    public:
//        typedef typename Iter::result_type value_type;
//        typedef const typename Iter::result_type* pointer;
//        typedef const typename Iter::result_type& reference;
        
        my_reverse_iterator() {}
    my_reverse_iterator(Iter i):p(i) {}
//        value_type operator*() const;
};


main() {
vector<int> v;
vector<int>::iterator it;
it = v.begin();
my_reverse_iterator<vector<int>::iterator> p;
my_reverse_iterator<vector<int>::iterator> q(it);
}

Thanks,

 
0
 

Seems I need to add the typedefs that didn't seem to inheret when i did it. Is this correct or does it work as a fluke?

this is correct; you need to have the typedefs for the iterator to work with iterator_traits<>. (specializing iterator_traits<> for your iterator is another way.) in a conformant implementation of libstdc++, you should have been able to inherit these typedefs from the iterator base class.

You
This article has been dead for over six months: Start a new discussion instead
Post:
Start New Discussion
Tags Related to this Article