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.

### 2696. Interaction between `make_shared` and `enable_shared_from_this` is underspecified

Section: 20.11.3.7 [util.smartptr.shared.create] Status: C++17 Submitter: Joe Gottman Opened: 2016-04-02 Last modified: 2017-07-30

Priority: 2

View other active issues in [util.smartptr.shared.create].

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

View all issues with C++17 status.

Discussion:

For each public constructor of `std::shared_ptr`, the standard says that constructor enables `shared_from_this` if that constructor is expected to initialize the internal `weak_ptr` of a contained `enable_shared_from_this<X>` object. But there are other ways to construct a `shared_ptr` than by using a public constructor. The template functions `make_shared` and `allocate_shared` both require calling a private constructor, since no public constructor can fulfill the requirement that at most one allocation is made. The standard does not specify that that private constructor enables `shared_from_this`; therefore in the following code:

>     struct Foo : public std::enable_shared_from_this<Foo> {};

>     int main() {
>       auto p = std::make_shared<Foo>();
>       assert(p == p->shared_from_this());
>       return 0;
>     }

it is unspecified whether the assertion will fail.

[2016-05 Issues Telecon]

Jonathan Wakely to provide updated wording.

[2016-08 Chicago]

Monday PM: Move to Tentatively Ready

Proposed resolution:

This wording is relative to N4582.

1. Change 20.11.3.7 [util.smartptr.shared.create] indicated:

   >     template<class T, class... Args> shared_ptr<T> make_shared(Args&&... args);
   >     template<class T, class A, class... Args>
   >       shared_ptr<T> allocate_shared(const A& a, Args&&... args);

   > > […]

   > > -6- Remarks: The `shared_ptr` constructor called by this function enables `shared_from_this` with the address of the newly constructed object of type `T`. Implementations should perform no more than one memory allocation. [Note: This provides efficiency equivalent to an intrusive smart pointer. — end note]