10

In C++20 (N4849), there is no exception safety wording for associative containers' extract() and insert(node_handle)/insert(hint, node_handle) methods.

But for merge(), there is this wording though:

Throws: Nothing unless the comparison object throws.

Location:
22.2.6 Associative containers [associative.reqmts]
Table 78: Associative container requirements (in addition to container) [tab:container.assoc.req]
Page 799

Apparently the orignal proposal (P0083R3) intended to make it no-throw (page 5):

Exception safety

If the container’s Compare function is no-throw (which is very common), then removing a node, modifying it, and inserting it is no-throw unless modifying the value throws. And if modifying the value does throw, it does so outside of the containers involved.

But why is there no say in the proposed wording later in that proposal?

rustyx
  • 80,671
  • 25
  • 200
  • 267
zwhconst
  • 1,352
  • 9
  • 19
  • Note that unlike `merge()`, `extract()` has to copy the container's allocator. But the Allocator model requires that copying be noexcept. It does seem like `extract()` could be noexcept if the comparator is. – John Zwinck Apr 10 '21 at 07:35

1 Answers1

4

The insert members taking a node handle have a precondition that the allocator in the node handle compares equal to the container's allocator.

The extract members taking an iterator have a precondition that the iterator is a valid dereferenceable iterator into the container.

The policy of the standard library is that functions with runtime preconditions are not noexcept.

The extract member taking a key_type argument can only throw if the comparison function throws, but that still means it can't be noexcept.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
  • It's not about a `noexcept` specifier in the method signature. It's about a statement in the standard promising that no exception is allowed when certain preconditions are met. For example, the standard has this for `std::list::splice()`: "`void splice(const_iterator position, list& x, const_iterator i)`, *Preconditions*: `i` is a valid dereferenceable iterator of `x`. Throws: Nothing."(n4849 page 832, [list.ops]) For now no such statement exists for `set`/`map`'s `extract()`/`insert()` in the standard. – zwhconst Apr 19 '21 at 13:48