This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of CD1 status.
Section: 23.2 [container.requirements], 23.2.8.2 [unord.req.except] Status: CD1 Submitter: Ion Gaztañaga Opened: 2007-12-22 Last modified: 2016-01-28
Priority: Not Prioritized
View all other issues in [container.requirements].
View all issues with CD1 status.
Discussion:
23.2 [container.requirements]p10 states:
Unless otherwise specified (see 23.2.2.3 and 23.2.5.4) all container types defined in this clause meet the following additional requirements:
- [...]
- no
erase()
,pop_back()
orpop_front()
function throws an exception.
23.3.5.4 [deque.modifiers] and 23.3.11.5 [vector.modifiers] offer
additional guarantees for deque
/vector insert()
and
erase()
members. However, 23.2 [container.requirements] p10
does not mention 23.2.8.2 [unord.req.except] that specifies exception
safety guarantees for unordered containers. In addition,
23.2.8.2 [unord.req.except] p1 offers the following guaratee for
erase()
:
No
erase()
function throws an exception unless that exception is thrown by the container's Hash or Pred object (if any).
Summary:
According to 23.2 [container.requirements] p10 no
erase()
function should throw an exception unless otherwise
specified. Although does not explicitly mention 23.2.8.2 [unord.req.except], this section offers additional guarantees
for unordered containers, allowing erase()
to throw if
predicate or hash function throws.
In contrast, associative containers have no exception safety guarantees
section so no erase()
function should throw, including
erase(k)
that needs to use the predicate function to
perform its work. This means that the predicate of an associative
container is not allowed to throw.
So:
erase(k)
for associative containers is not allowed to throw. On
the other hand, erase(k)
for unordered associative containers
is allowed to throw.
erase(q)
for associative containers is not allowed to throw. On
the other hand, erase(q)
for unordered associative containers
is allowed to throw if it uses the hash or predicate.
erase(q)
is
allowed to throw, the destructor of the object would need to rethrow the
exception or swallow it, leaving the object registered.
Proposed resolution:
Create a new sub-section of 23.2.7 [associative.reqmts] (perhaps [associative.req.except]) titled "Exception safety guarantees".
1 For associative containers, no
clear()
function throws an exception.erase(k)
does not throw an exception unless that exception is thrown by the container's Pred object (if any).2 For associative containers, if an exception is thrown by any operation from within an
insert()
function inserting a single element, theinsert()
function has no effect.3 For associative containers, no
swap
function throws an exception unless that exception is thrown by the copy constructor or copy assignment operator of the container's Pred object (if any).
Change 23.2.8.2 [unord.req.except]p1:
For unordered associative containers, no
clear()
function throws an exception.Noerase(k)
functiondoes not throwsan exception unless that exception is thrown by the container's Hash or Pred object (if any).
Change 23.2 [container.requirements] p10 to add references to new sections:
Unless otherwise specified (see [deque.modifiers],
and[vector.modifiers], [associative.req.except], [unord.req.except]) all container types defined in this clause meet the following additional requirements:
Change 23.2 [container.requirements] p10 referring to swap
:
- no
swap()
function throws an exceptionunless that exception is thrown by the copy constructor or assignment operator of the container's Compare object (if any; see [associative.reqmts]).