user12463032
user12463032

Reputation:

Can I use reverse iterator as ForwardIt?

Based on this question. std::rotate is defined the following way:

template< class ForwardIt >
constexpr ForwardIt rotate( ForwardIt first, ForwardIt n_first, ForwardIt last );

Looking at the name ForwardIt, it expects forward iterator.

Question: assuming that my initial collection supports forward iterator (e.g. vector), can I use reverse iterators here? Why/why not?

Looking at, for example, http://www.cplusplus.com/reference/iterator/reverse_iterator/, I don't understand if what is returned be considered a forward iterator. Do I have to guarantee that reverse iterator satisfies forward iterator's properties? In this case, how can I check that it's true? vector::rbegin() documentation doesn't mention if it's the case.

Upvotes: 0

Views: 284

Answers (2)

HolyBlackCat
HolyBlackCat

Reputation: 96043

Look at the iterator_category member typedef. Iterators report their category by setting it to the appropriate tag.

[ https://en.cppreference.com/w/cpp/iterator/reverse_iterator ]

iterator_category — If std::iterator_traits<Iter>::iterator_category models std::derived_from<std::random_access_iterator_tag>, this is std::random_access_iterator_tag. Otherwise, this is std::iterator_traits<Iter>::iterator_category unchanged.

Given that the original iterator must be at least bidirectional (see link), it means that the resulting iterator is either random-access (if the original iterator is at least random-access), or bidirectional (otherwise).

(std::derived_from is used here because category A inherits from category B when A is a subset of B, meaning the requirements of A are a superset of the requirements of B. The only thing that inherits from random_access_iterator_tag is contiguous_iterator_tag.)

Upvotes: 2

cigien
cigien

Reputation: 60208

The requirements for reverse_iterator are given in reverse.iter.requirements:

The template parameter Iterator shall either meet the requirements of a Cpp17BidirectionalIterator ([bidirectional.iterators]) or model bidirectional_­iterator ([iterator.concept.bidir]).

and the requirements for iterator.concept.bidir:

The bidirectional_­iterator concept adds the ability to move an iterator backward as well as forward.

So yes, a reverse_iterator can be used as a forward_iterator.

Upvotes: 2

Related Questions