2455. Allocator default construction should be allowed to throw

Section: 20.5.3.5 [allocator.requirements] Status: C++17 Submitter: Pablo Halpern Opened: 2014-11-11 Last modified: 2017-07-30

Priority: Not Prioritized

View other active issues in [allocator.requirements].

View all other issues in [allocator.requirements].

View all issues with C++17 status.

Discussion:

20.5.3.5 [allocator.requirements]/4 in the 2014-10 WP (N4140), says:

An allocator type X shall satisfy the requirements of CopyConstructible (17.6.3.1). The X::pointer, X::const_pointer, X::void_pointer, and X::const_void_pointer types shall satisfy the requirements of NullablePointer (17.6.3.3). No constructor, comparison operator, copy operation, move operation, or swap operation on these types shall exit via an exception. X::pointer and X::const_pointer shall also satisfy the requirements for a random access iterator (24.2).

The words "these types" would normally apply only to the previous sentence only, i.e., only to the pointer types. However, an alternative reading would be that the allocator constructors themselves cannot throw. The change to the vector and string default constructors, making them unconditionally noexcept depends on this alternative reading.

I believe that the wording in the standard is not intended to forbid throwing default constructors for allocators. Indeed, I believe that allocators do not require default constructors and that if they provide a default constructor they should be allowed to throw.

In addition, the noexcept specifications for the string and vector default constructors should be changed to make them conditional.

[2015-01-18 Library reflector vote]

The issue has been identified as Tentatively Ready based on six votes in favour.

Proposed resolution:

  1. Change 20.5.3.5 [allocator.requirements] p4 as indicated:

    An allocator type X shall satisfy the requirements of CopyConstructible (17.6.3.1). The X::pointer, X::const_pointer, X::void_pointer, and X::const_void_pointer types shall satisfy the requirements of NullablePointer (17.6.3.3). No constructor, comparison operator, copy operation, move operation, or swap operation on these pointer types shall exit via an exception. X::pointer and X::const_pointer shall also satisfy the requirements for a random access iterator (24.2).

  2. Change 24.3.2 [basic.string] following p5, class template basic_string synopsis, as indicated: (This change assumes that N4258 has been applied, as voted on in Urbana on 2014-11-08)

    // 21.4.2, construct/copy/destroy:
    basic_string() noexcept(noexcept(Allocator())) : basic_string(Allocator()) { }
    

    An alternative formulation of the above would be:

    // 21.4.2, construct/copy/destroy:
    basic_string() noexcept(is_nothrow_default_constructible<Allocator>{}) : basic_string(Allocator()) { }
    
  3. Change 26.3.11.1 [vector.overview] following p2, class template vector synopsis, as indicated: (This change assumes that N4258 has been applied, as voted on in Urbana on 2014-11-08)

    // 23.3.6.2, construct/copy/destroy:
    vector() noexcept(noexcept(Allocator())) : vector(Allocator()) { }
    

    An alternative formulation of the above would be:

    // 23.3.6.2, construct/copy/destroy:
    vector() noexcept(is_nothrow_default_constructible<Allocator>{}) : vector(Allocator()) { }