2944. LWG 2905 accidentally removed requirement that construction of the deleter doesn't throw an exception

Section: 20.3.1.3.2 [unique.ptr.single.ctor] Status: C++20 Submitter: Tim Song Opened: 2017-03-11 Last modified: 2021-02-25

Priority: 0

View all other issues in [unique.ptr.single.ctor].

View all issues with C++20 status.

Discussion:

The wording simplification in LWG 2905 accidentally deleted the requirement that construction of the deleter doesn't throw an exception. While this isn't the end of the world since any exception will just run into the noexcept on the constructor and result in a call to std::terminate(), the other unique_ptr constructors still have a similar no-exception Requires: clause, leaving us in the odd situation where throwing an exception results in undefined behavior for some constructors and terminate() for others. If guaranteeing std::terminate() on exception is desirable, that should be done across the board.

The proposed wording below simply restores the nothrow requirement along with the Copy/MoveConstructible requirement. Wording for the other alternative (guaranteed std::terminate()) can be produced if desired.

[2017-03-16, Daniel comments]

The publication of the new working draft is awaited, before proposed wording against that new working draft is formally possible.

[2017-05-03, Tim comments]

The suggested wording has been moved to the PR section now that the new working draft is available.

[2017-07 Toronto Wed Issue Prioritization]

Priority 0; Move to Ready

Proposed resolution:

This wording is relative to N4659.

  1. Insert a paragraph after 20.3.1.3.2 [unique.ptr.single.ctor] p11:

    unique_ptr(pointer p, see below d1) noexcept;
    unique_ptr(pointer p, see below d2) noexcept;
    

    -9- The signature of these constructors depends upon whether D is a reference type. If D is a non-reference type A, then the signatures are:

    […]

    -10- If D is an lvalue reference type A&, then the signatures are:

    […]

    -11- If D is an lvalue reference type const A&, then the signatures are:

    […]

    -??- Requires: For the first constructor, if D is not a reference type, D shall satisfy the requirements of CopyConstructible and such construction shall not exit via an exception. For the second constructor, if D is not a reference type, D shall satisfy the requirements of MoveConstructible and such construction shall not exit via an exception.