685. reverse_iterator/move_iterator difference has invalid signatures

Section: 27.5.1.3.19 [reverse.iter.opdiff], 27.5.3.3.14 [move.iter.nonmember] Status: CD1 Submitter: Bo Persson Opened: 2007-06-10 Last modified: 2016-02-10

Priority: Not Prioritized

View all issues with CD1 status.

Discussion:

In C++03 the difference between two reverse_iterators

ri1 - ri2

is possible to compute only if both iterators have the same base iterator. The result type is the difference_type of the base iterator.

In the current draft, the operator is defined as 27.5.1.3.19 [reverse.iter.opdiff]

template<class Iterator1, class Iterator2> 
typename reverse_iterator<Iterator>::difference_type 
   operator-(const reverse_iterator<Iterator1>& x, 
                    const reverse_iterator<Iterator2>& y);

The return type is the same as the C++03 one, based on the no longer present Iterator template parameter.

Besides being slightly invalid, should this operator work only when Iterator1 and Iterator2 has the same difference_type? Or should the implementation choose one of them? Which one?

The same problem now also appears in operator-() for move_iterator 27.5.3.3.14 [move.iter.nonmember].

Proposed resolution:

Change the synopsis in 27.5.1.1 [reverse.iterator]:

template <class Iterator1, class Iterator2> 
  typename reverse_iterator<Iterator>::difference_type auto operator-( 
    const reverse_iterator<Iterator1>& x, 
    const reverse_iterator<Iterator2>& y) -> decltype(y.current - x.current);

Change 27.5.1.3.19 [reverse.iter.opdiff]:

template <class Iterator1, class Iterator2> 
  typename reverse_iterator<Iterator>::difference_type auto operator-( 
    const reverse_iterator<Iterator1>& x, 
    const reverse_iterator<Iterator2>& y) -> decltype(y.current - x.current);

Returns: y.current - x.current.

Change the synopsis in 27.5.3.1 [move.iterator]:

template <class Iterator1, class Iterator2> 
  typename move_iterator<Iterator>::difference_type auto operator-( 
    const move_iterator<Iterator1>& x, 
    const move_iterator<Iterator2>& y) -> decltype(x.base() - y.base());

Change 27.5.3.3.14 [move.iter.nonmember]:

template <class Iterator1, class Iterator2> 
  typename move_iterator<Iterator>::difference_type auto operator-( 
    const move_iterator<Iterator1>& x, 
    const move_iterator<Iterator2>& y) -> decltype(x.base() - y.base());

Returns: x.base() - y.base().

[ Pre Bellevue: This issue needs to wait until the auto -> return language feature goes in. ]