Title
LWG 2472: actually an incompatibility with C++03
Status
new
Section
[reverse.iterators]
Submitter
Hubert Tong

Created on 2017-01-28.00:00:00 last changed 86 months ago

Messages

Date: 2017-03-14.03:14:09

Proposed resolution:

This wording is relative to N4618.

  1. Modify [reverse.iterators], class template reverse_iterator synopsis, as indicated:

    template <class Iterator1, class Iterator2>
      constexpr bool operator==(
        const reverse_iterator<Iterator1>& x,
        const reverse_iterator<Iterator2>& y);
    template <class Iterator1, class Iterator2>
      constexpr bool operator<(
        const reverse_iterator<Iterator1>& x,
        const reverse_iterator<Iterator2>& y);
    template <class Iterator1, class Iterator2>
      constexpr bool operator!=(
        const reverse_iterator<Iterator1>& x,
        const reverse_iterator<Iterator2>& y);
    template <class Iterator1, class Iterator2>
      constexpr bool operator>(
        const reverse_iterator<Iterator1>& x,
        const reverse_iterator<Iterator2>& y);
    template <class Iterator1, class Iterator2>
      constexpr bool operator>=(
        const reverse_iterator<Iterator1>& x,
        const reverse_iterator<Iterator2>& y);
    template <class Iterator1, class Iterator2>
      constexpr bool operator<=(
        const reverse_iterator<Iterator1>& x,
        const reverse_iterator<Iterator2>& y);
    template <class Iterator>
      constexpr bool operator==(
        const reverse_iterator<Iterator>& x,
        const reverse_iterator<Iterator>& y);
    template <class Iterator>
      constexpr bool operator<(
        const reverse_iterator<Iterator>& x,
        const reverse_iterator<Iterator>& y);
    template <class Iterator>
      constexpr bool operator!=(
        const reverse_iterator<Iterator>& x,
        const reverse_iterator<Iterator>& y);
    template <class Iterator>
      constexpr bool operator>(
        const reverse_iterator<Iterator>& x,
        const reverse_iterator<Iterator>& y);
    template <class Iterator>
      constexpr bool operator>=(
        const reverse_iterator<Iterator>& x,
        const reverse_iterator<Iterator>& y);
    template <class Iterator>
      constexpr bool operator<=(
        const reverse_iterator<Iterator>& x,
        const reverse_iterator<Iterator>& y);
    
  2. Modify [reverse.iter.op==] as indicated:

    template <class Iterator1, class Iterator2>
      constexpr bool operator==(
        const reverse_iterator<Iterator1>& x,
        const reverse_iterator<Iterator2>& y);
    template <class Iterator>
      constexpr bool operator==(
        const reverse_iterator<Iterator>& x,
        const reverse_iterator<Iterator>& y);
    

    -1- Returns: x.current == y.current.

  3. Modify [reverse.iter.op<] as indicated:

    template <class Iterator1, class Iterator2>
      constexpr bool operator<(
        const reverse_iterator<Iterator1>& x,
        const reverse_iterator<Iterator2>& y);
    template <class Iterator>
      constexpr bool operator<(
        const reverse_iterator<Iterator>& x,
        const reverse_iterator<Iterator>& y);
    

    -1- Returns: x.current > y.current.

  4. Modify [reverse.iter.op!=] as indicated:

    template <class Iterator1, class Iterator2>
      constexpr bool operator!=(
        const reverse_iterator<Iterator1>& x,
        const reverse_iterator<Iterator2>& y);
    template <class Iterator>
      constexpr bool operator!=(
        const reverse_iterator<Iterator>& x,
        const reverse_iterator<Iterator>& y);
    

    -1- Returns: x.current != y.current.

  5. Modify [reverse.iter.op>] as indicated:

    template <class Iterator1, class Iterator2>
      constexpr bool operator>(
        const reverse_iterator<Iterator1>& x,
        const reverse_iterator<Iterator2>& y);
    template <class Iterator>
      constexpr bool operator>(
        const reverse_iterator<Iterator>& x,
        const reverse_iterator<Iterator>& y);
    

    -1- Returns: x.current < y.current.

  6. Modify [reverse.iter.op>=] as indicated:

    template <class Iterator1, class Iterator2>
      constexpr bool operator>=(
        const reverse_iterator<Iterator1>& x,
        const reverse_iterator<Iterator2>& y);
    template <class Iterator>
      constexpr bool operator>=(
        const reverse_iterator<Iterator>& x,
        const reverse_iterator<Iterator>& y);
    

    -1- Returns: x.current <= y.current.

  7. Modify [reverse.iter.op<=] as indicated:

    template <class Iterator1, class Iterator2>
      constexpr bool operator<=(
        const reverse_iterator<Iterator1>& x,
        const reverse_iterator<Iterator2>& y);
    template <class Iterator>
      constexpr bool operator<=(
        const reverse_iterator<Iterator>& x,
        const reverse_iterator<Iterator>& y);
    

    -1- Returns: x.current >= y.current.

Date: 2017-03-15.00:00:00

[ 2017-03-04, Kona ]

Set priority to 4. STL to write a paper deprecating relops Alisdair to provide an example for Annex C.

Date: 2017-01-28.00:00:00

Further to LWG 2472, the case of reverse_iterator comparisons is a regression introduced by LWG 280.

Consider the following program:

#include <utility>
#include <iterator>

using namespace std::rel_ops;

bool f(std::reverse_iterator<int *> it) { return it != it; }

Under C++03, the operator!= in lib.reverse.iterator is more specialized than the operator!= in std::rel_ops.

Following LWG 280, neither operator!= candidate is more specialized than the other. The program is observed to fail with libc++.

Online compiler example, see here.

Suggested resolution:

Reintroduce the homogeneous comparison operators from C++03 alongside the new ones.

History
Date User Action Args
2017-03-14 03:14:09adminsetmessages: + msg9109
2017-02-01 22:08:24adminsetmessages: + msg8835
2017-01-28 00:00:00admincreate