Title
What should happen when an exception is thrown on resizing `std::deque`, `std::forward_list`, or `std::list`?
Status
new
Section
[deque.capacity][forward.list.modifiers][list.capacity]
Submitter
Jiang An

Created on 2025-03-15.00:00:00 last changed yesterday

Messages

Date: 2025-10-16.14:52:11

Proposed resolution:

This wording is relative to N5014.

  1. Modify [deque.capacity] as indicated:

    constexpr void resize(size_type sz);
    

    -1- Preconditions: `T` is Cpp17MoveInsertable and Cpp17DefaultInsertable into `deque`.

    -2- Effects: If sz < size() is `true`, erases the last `size() - sz` elements from the sequence. Otherwise, appends `sz - size()` default-inserted elements to the sequence. If an exception is thrown, there is no effect on the container.

    constexpr void resize(size_type sz, const T& c);
    

    -3- Preconditions: `T` is Cpp17CopyInsertable into `deque`.

    -4- Effects: If sz < size() is `true`, erases the last `size() - sz` elements from the sequence. Otherwise, appends `sz - size()` copies of `c` to the sequence. If an exception is thrown, there is no effect on the container.

  2. Modify [list.capacity] as indicated:

    constexpr void resize(size_type sz);
    

    -1- Preconditions: `T` is Cpp17DefaultInsertable into `list`.

    -2- Effects: If size() < sz is `true`, appends `sz - size()` default-inserted elements to the sequence. If sz <= size() is `true`, equivalent to:

    list<T>::iterator it = begin();
    advance(it, sz);
    erase(it, end());
    
    If an exception is thrown, there is no effect on the container.

    constexpr void resize(size_type sz, const T& c);
    

    -3- Preconditions: `T` is Cpp17CopyInsertable into `list`.

    -4- Effects: As if by Equivalent to:

    if (sz < size()
      insert(end(), sz-size(), c);
    else if (sz < size()) {
      iterator i = begin();
      advance(it, sz);
      erase(it, end());
    }
    else
      ;           // do nothing
    

Date: 2025-10-15.00:00:00

[ 2025-10-16; Jonathan provides wording ]

LWG 4106 already fixed this for `std::forward_list`. For `std::list` the "If an exception is thrown, there are no effects" wording in [list.modifiers] p2 doesn't apply to `std::list::resize` because it's in a different subclause ([list.capacity]). We can fix that though.

Date: 2025-10-15.00:00:00

[ 2025-10-16; Reflector poll ]

Set priority to 3 after reflector poll.

Date: 2025-03-15.00:00:00

Currently, `std::vector` and `std::inplace_vector`'s `resize` functions are specified to have no effects on the container when an exception is throwing on appending. However, such specification seem to be missing for `std::deque`, `std::forward_list`, and `std::list`.

Is such difference intented? Do we want to roll back the status of container when the appending is partially done?

Daniel:

The specific `resize` exception guarantee for `std::vector` came from resolving LWG 2033 and were later effectively copied to `std::inplace_vector` because that container's specification should resemble as much as possible that of `std::vector`.

History
Date User Action Args
2025-10-16 14:52:11adminsetmessages: + msg15187
2025-10-16 14:52:11adminsetmessages: + msg15186
2025-10-16 14:52:11adminsetmessages: + msg15185
2025-03-15 00:00:00admincreate