Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reverse iterator won't compile

Tags:

c++

I'm trying to compile a reverse iterator but my attempts to do so give a horrid mess. The minimal example of the code is...

#include <iostream>
#include <vector>
#include <algorithm>

class frag {
    public:
        void print (void) const;
    private:
        std::vector<int> a;
};

void frag::print (void) const
{
    for (std::vector<int>::reverse_iterator iter = a.begin ();
         iter                                   != a.end ();
         ++iter) {
        std::cout << *iter << std::endl;
    }
}

and attempting to compile it produces the following...

In file included from /usr/include/c++/4.4/bits/stl_algobase.h:69,
             from /usr/include/c++/4.4/bits/char_traits.h:41,
             from /usr/include/c++/4.4/ios:41,
             from /usr/include/c++/4.4/ostream:40,
             from /usr/include/c++/4.4/iostream:40,
             from frag.cpp:1:
/usr/include/c++/4.4/bits/stl_iterator.h: In constructor ‘std::reverse_iterator<_Iterator>::reverse_iterator(const std::reverse_iterator<_Iter>&) [with _Iter = __gnu_cxx::__normal_iterator<const int*, std::vector<int, std::allocator<int> > >, _Iterator = __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >]’:
frag.cpp:14:   instantiated from here
/usr/include/c++/4.4/bits/stl_iterator.h:134: error: no matching function for call to ‘__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >::__normal_iterator(__gnu_cxx::__normal_iterator<const int*, std::vector<int, std::allocator<int> > >)’
/usr/include/c++/4.4/bits/stl_iterator.h:686: note: candidates are: __gnu_cxx::__normal_iterator<_Iterator, _Container>::__normal_iterator(const _Iterator&) [with _Iterator = int*, _Container = std::vector<int, std::allocator<int> >]
/usr/include/c++/4.4/bits/stl_iterator.h:683: note:                 __gnu_cxx::__normal_iterator<_Iterator, _Container>::__normal_iterator() [with _Iterator = int*, _Container = std::vector<int, std::allocator<int> >]
/usr/include/c++/4.4/bits/stl_iterator.h:669: note:                 __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >::__normal_iterator(const __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >&)

There was a question on this subject yesterday but I don't think this is the same as it isn't a template. If a vector is declared in a similar way locally it is quite happy. (g++ on Ubuntu 10.4).

Anyone know what I should do?

like image 314
Brian Hooper Avatar asked Jul 01 '10 14:07

Brian Hooper


4 Answers

You need to use const_reverse_iterator (print is a const function so a is const) and a.rbegin() and a.rend() rather than begin() and end().

like image 167
CB Bailey Avatar answered Sep 28 '22 08:09

CB Bailey


Two things that may cause an issue in your code:

  1. Your print() function is declared const, so you'll (probably need to or should) use a const_reverse_iterator.

  2. You're creating a reverse_iterator from a normal_iterator (std::vector<T>::begin())

like image 27
rubenvb Avatar answered Sep 28 '22 06:09

rubenvb


You have to assign a reverse iterator to a reverse iterator. The same with comparison. Reverse iterators can be obtained using methods rbegin and rend:

for (std::vector<int>::reverse_iterator iter = a.rbegin(); iter != a.rend(); ++iter);

EDIT (for completeness) As others have noticed, const_reverse_iterator will be necessary here as well.

like image 29
Michał Trybus Avatar answered Sep 28 '22 07:09

Michał Trybus


The above answers already point out that a const_reverse_iterator with rbegin/rend is needed in this case.

In addition to that, a good practice would be to use crbegin or crend (introduced in C++11) to explicitly indicate you are requesting the const version of the iterator since the print function is const.

like image 28
greedy52 Avatar answered Sep 28 '22 08:09

greedy52