This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++17 status.

### 2685. `shared_ptr` deleters must not not throw on move construction

Section: 20.11.3.2 [util.smartptr.shared.const] Status: C++17 Submitter: Jonathan Wakely Opened: 2016-05-03 Last modified: 2017-07-30

Priority: 0

View all other issues in [util.smartptr.shared.const].

View all issues with C++17 status.

Discussion:

In 20.11.3.2 [util.smartptr.shared.const] p8 the `shared_ptr` constructors taking a deleter say:

> The copy constructor and destructor of `D` shall not throw exceptions.

It's been pointed out that this doesn't forbid throwing moves, which makes it difficult to avoid a leak here:

    struct D {
      D() = default;
      D(const D&) noexcept = default;
      D(D&&) { throw 1; }
      void operator()(int* p) const { delete p; }
    };

    shared_ptr<int> p{new int, D{}};

"The copy constructor" should be changed to reflect that the chosen constructor might not be a copy constructor, and that copies made using any constructor must not throw.

N.B. the same wording is used for the allocator argument, but that's redundant because the `Allocator` requirements already forbid exceptions when copying or moving.

Proposed resolution:

[Drafting note: the relevant expressions we're concerned about are enumerated in the `CopyConstructible` and `MoveConstructible` requirements, so I see no need to repeat them by saying something clunky like "Initialization of an object of type `D` from an expression of type (possibly const) `D` shall not throw exceptions", we can just refer to them. An alternative would be to define `NothrowCopyConstructible`, which includes `CopyConstructible` but requires that construction and destruction do not throw.]

Change 20.11.3.2 [util.smartptr.shared.const] p8:

> `D` shall be `CopyConstructible` and such construction shall not throw exceptions. The copy constructor and destructor of `D` shall not throw exceptions.