Is there a C++11 replacement for boost::reverse_iterator?

126 views Asked by At

I've have an application that has been running on C++03 that makes use of boost::reverse_iterator. I've finally been able to upgrade to a C++11 compiler, and I've noticed that boost/iterator/reverse_iterator.hpp is no longer installed (I'm using Boost 1.74.0).

I assume that it's because C++11's std::reverse_iterator takes the place of it. Is that the case?

I tried using std::reverse_iterator in place of boost::reverse_iterator, but it does not work for me. The reason is that my base iterator, although it is random-access, is not a true STL "random access iterator" because its reference type is a proxy, not a true reference. When I use std::reverse_iterator, it tries to take the address of my "reference".

Is there a C++11 replacement for boost::reverse_iterator, or do I need to write one from scratch for my application?

EDIT: Sorry - you're right that boost::reverse_iterator is still there in boost 1.74.0. I had a problem with my include paths, and I missed it.

If I use boost::reverse_iterator, everything is working for me.

If std::reverse_iterator is supposed to work with proxy reference types, then I'm curious about why the code didn't work. More precisely, I can see why it fails, but it looks to me that std::reverse_iterator doesn't seem to fully support proxy types.

In particular, std::reverse_iterator's operator->() does not work for proxy types. That operator needs to return a pointer to a value type. It tries to do this by dereferencing the iterator and then taking the address of the value it gets. In this case, dereferencing the iterator returns a proxy, not a reference, and taking its address is taking the address of an rvalue, which generates this error with g++ 8.3.1:

/usr/include/c++/8/bits/stl_iterator.h:184:32: error: cannot bind non-const lvalue reference of type 'MyProxyType&' to an rvalue of type 'std::reverse_iterator<MyIteratorType>::reference' {aka 'MyProxyType'}
   { return std::__addressof(operator*()); }

If I use std::reverse_iterator and replace instances of i-> with (*i)., then it works, but that's not how iterators are supposed to behave.

My iterator (MyIteratorType) is built using boost::iterator_adaptor, and that documentation says they use unspecified tricks to get operator-> to work for proxy types. It looks like boost::reverse_iterator builds its operator-> on top of the base iterator's version, so it leverages these tricks, but std::reverse_iterator does not.

If anyone knows more detail, I'd be interested!

0

There are 0 answers