This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of Tentatively Ready status.
unique_copy passes arguments to its predicate backwardsSection: 26.7.9 [alg.unique] Status: Tentatively Ready Submitter: Jonathan Wakely Opened: 2025-05-29 Last modified: 2025-10-17
Priority: Not Prioritized
View other active issues in [alg.unique].
View all other issues in [alg.unique].
View all issues with Tentatively Ready status.
Discussion:
For the unique algorithms, 26.7.9 [alg.unique] p1 says:
1. Letpredbeequal_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. Letpredbeequal_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).
[2025-10-17; Reflector poll.]
Set status to Tentatively Ready after six votes in favour during reflector poll.
Fixed misplaced ) in the (6.1) change as pointed out on reflector,
and rebased on N5014.
"I remain inconvinced that this actually matters given the equivalence relation requirement."
Proposed resolution:
This wording is relative to N5014.
Modify 26.7.9 [alg.unique] as indicated:
6. Letpredbeequal_to{}for the overloads with no parameterpred, and let E(i) 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.