2319. basic_string's move constructor should not be noexcept

Section: [string.cons] Status: NAD Submitter: Stephan T. Lavavej Opened: 2013-09-21 Last modified: 2017-03-21 22:54:52 UTC

Priority: 1

View all other issues in [string.cons].

View all issues with NAD status.


In debugging implementations, containers (including basic_string) may need to own dynamically allocated helper objects at all times, including in their default-constructed and moved-from states. This means that their default constructors and move constructors may throw exceptions. Therefore, the Standard should not mark them as noexcept. (Other implementations will still be permitted to add noexcept.)

[2014-02, Issaquah : move to Ready]

The issue discussion was highly controversial: The arguments in favour was that implementations exist that always need to allocate memory even for the move operations (similar as for some other containers) and that this cleans up an inconsistency between std::string and other container types. Counter arguments were that potentially throwing move operations reduce much of the advantages of move-support, e.g. in vector<string>.

straw poll: accept wording in the issue
SF 4 WF 4 N 0 WA 1 SA 1

straw poll: 14 or 17?
C++14: 4 C++17: 4

Move to Ready for C++17, as too close to 14 DIS without strong consensus.

It was suggested to introduce a special library vocabulary that specifies a "normative encouragement to not throw exceptions" for functions like these.

NJ: I offer to write a proposal to add encouragement for not throwing ... "noexcept in italics means should not throw"

[2014/11 Urbana]

Resolved by paper N4258


Richard Smith pointed out that N4258 explicitly decided not to change this call; leaving it as noexcept. In response, I am changing the resolution of this issue from 'Resolved' to 'NAD'

Proposed resolution:

This wording is relative to N3691.

  1. In 23.4.3 [basic.string]/5, class template basic_string synopsis, and [string.cons]/2 change as indicated:

    basic_string(basic_string&& str) noexcept;
  2. Edit [string.cons]/17 as indicated:

    basic_string(const basic_string& str, const Allocator& alloc);
    basic_string(basic_string&& str, const Allocator& alloc);


    -17- Throws: The second form throws nothing if alloc == str.get_allocator()..