https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120386

            Bug ID: 120386
           Summary: std::unique_copy uses the output type for comparisons
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Keywords: rejects-valid
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: redi at gcc dot gnu.org
  Target Milestone: ---

#include <algorithm>

struct X { X(int){} };

void uniq(const int* first, const int* last, X* out)
{
  std::unique_copy(first, last, out);
}

/usr/include/c++/14/bits/predefined_ops.h:117:23: error: no match for
‘operator==’ (operand types are ‘X’ and ‘const int’)
  117 |       { return *__it1 == *__it2; }
      |                ~~~~~~~^~~~~~~~~

When the output iterator has category std::forward_iterator_tag we choose an
implementation that compares the output value with the input value, even though
they might be different types.

The standard is clear (since C++98) that the comparisons should be on two
values from the input range:

  Copies only the first element from every consecutive group of equal elements
referred
  to by the iterator i in the range [first, last) for which the following
corresponding
  conditions hold: *i == *(i - 1) or pred(*i, *(i - 1)) != false

We seem to have done this wrong since the beginning of time (at least since
2001).

Reply via email to