This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.
unique_copy
passes arguments to its predicate backwardsSection: 26.7.9 [alg.unique] Status: New Submitter: Jonathan Wakely Opened: 2025-05-29 Last modified: 2025-05-29
Priority: Not Prioritized
View other active issues in [alg.unique].
View all other issues in [alg.unique].
View all issues with New status.
Discussion:
For the unique
algorithms, 26.7.9 [alg.unique] p1 says:
1. Letpred
beequal_to{}
for the overloads with no parameterpred
, and let E be
- (1.1) —
bool(pred(*(i - 1), *i))
for the overloads in namespacestd
;- (1.2) —
bool(invoke(comp, invoke(proj, *(i - 1)), invoke(proj, *i)))
for the overloads in namespaceranges
.
However for the unique_copy
algorithms, 26.7.9 [alg.unique] p6 says
that the arguments *i
and *(i-1)
should be reversed:
6. Letpred
beequal_to{}
for the overloads with no parameterpred
, and let E be
- (6.1) —
bool(pred(*i, *(i - 1)))
for the overloads in namespacestd
;- (6.2) —
bool(invoke(comp, invoke(proj, *i), invoke(proj, *(i - 1))))
for the overloads in namespaceranges
.
This reversed order is consistent with the documentation for
SGI STL unique_copy
,
although the docs for
SGI STL unique
show reversed arguments too, and the C++ standard doesn't match that.
A survey of known implementations shows that all three of libstdc++, libc++,
and MSVC STL use the pred(*(i - 1), *i)
order for all of std::unique
,
std::unique_copy
, ranges::unique
, and ranges::unique_copy
. The range-v3
library did the same, and even the SGI STL did too (despite what its docs said).
Only two implementations were found which match the spec and use a different
argument order for unique
and unique_copy
, Casey Carter's (cmcstl2) and
Fraser Gordon's.
In the absence of any known rationale for unique
and unique_copy
to differ,
it seems sensible to make unique_copy
more consistent with unique
(and with the majority of implementations stretching back three decades).
Proposed resolution:
This wording is relative to N5008.
Modify 26.7.9 [alg.unique] as indicated:
6. Letpred
beequal_to{}
for the overloads with no parameterpred
, and let E be
- (6.1) —
bool(pred(
for the overloads in namespace*i,*(i - 1)), *i)std
;- (6.2) —
bool(invoke(comp,
for the overloads in namespaceinvoke(proj, *i),invoke(proj, *(i - 1)), invoke(proj, *i)))ranges
.