Section: 23.2.7.1 [associative.reqmts.general], 23.2.8.1 [unord.req.general] Status: New Submitter: Joaquín M López Muñoz Opened: 2021-08-04 Last modified: 2024-01-29
Priority: 3
View other active issues in [associative.reqmts.general].
View all other issues in [associative.reqmts.general].
View all issues with New status.
Discussion:
For the expression a.merge(a2)
, it is not explicitly stated whether a2
can be the
same object as a
. libstdc++-v3 and libc++ seemingly assume this is not allowed, as the following code
produces an infinite loop with both standard library implementations:
#include <set> int main() { std::multiset<int> c={0, 0}; c.merge(c); }
A strict reading of postconditions seems to ban the case where a
and a2
are the same:
23.2.7.1 [associative.reqmts.general]: "Iterators referring to the transferred elements […]
now behave as iterators into a
, not into a2
": if a
and a2
are the same,
a transferred iterator can't be both an iterator to a
and not an iterator to a2
.
23.2.8.1 [unord.req.general]: "Iterators referring to the transferred elements and all iterators
referring to a
will be invalidated, but iterators to elements remaining in a2
will remain valid":
if a
and a2
are the same, an iterator can't both be invalidated and remain valid.
Even if a provision is made that, when a
and a2
are the same, no elements are transferred by
convention, 23.2.8.1 [unord.req.general] would still implicitly ban the case, as all iterators would be
invalidated but the iterators to the remaining elements (again, all iterators) would remain valid, which is
contradictory.
std::list
take inconsistent approaches:
splice(const_iterator position, list& x)
requires that source and destination be not the same.
splice(const_iterator position, list& x, const_iterator i)
implicitly allows addressof(x) == this
,
as the case position == i
is taken care of.
std::list::merge
explicitly allows the case addressof(x) == this
(resulting in a no-op).
[2021-08-20; Reflector poll]
Set priority to 3 after reflector poll.
Tim Song commented:
"I think the current PR of LWG2414 bans this code,
but we might want to have consistency with list::merge
instead."
Proposed resolution: