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.
Section: 24.2.7.1 [associative.reqmts.general], 24.2.8.1 [unord.req.general] Status: New Submitter: Joaquín M López Muñoz Opened: 2021-08-04 Last modified: 2021-08-20
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:
24.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.
24.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, 24.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.
For context, analogous operations for 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: