3577. Merging an (unordered) associative container with itself

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:

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.

For context, analogous operations for std::list take inconsistent approaches:

[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: