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

### 710. Missing postconditions

Section: 20.3.2.2 [util.smartptr.shared] Status: CD1 Submitter: Peter Dimov Opened: 2007-08-24 Last modified: 2016-01-28

Priority: Not Prioritized

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

View all issues with CD1 status.

Discussion:

A discussion on comp.std.c++ has identified a contradiction in the `shared_ptr` specification. The `shared_ptr` move constructor and the cast functions are missing postconditions for the `get()` accessor.

[ Bellevue: ]

> Move to "ready", adopting the first (Peter's) proposed resolution.

> Note to the project editor: there is an editorial issue here. The wording for the postconditions of the casts is slightly awkward, and the editor should consider rewording "If w is the return value...", e. g. as "For a return value w...".

Proposed resolution:

Add to 20.3.2.2.2 [util.smartptr.shared.const]:

>     shared_ptr(shared_ptr&& r);
>     template<class Y> shared_ptr(shared_ptr<Y>&& r);

> > Postconditions: `*this` shall contain the old value of `r`. `r` shall be empty. `r.get() == 0`.

Add to 20.3.2.2.10 [util.smartptr.shared.cast]:

>     template<class T, class U> shared_ptr<T> static_pointer_cast(shared_ptr<U> const& r);

> > Postconditions: If `w` is the return value, `w.get() == static_cast<T*>(r.get()) && w.use_count() == r.use_count()`.

>     template<class T, class U> shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const& r);

> > Postconditions: If `w` is the return value, `w.get() == dynamic_cast<T*>(r.get())`.

>     template<class T, class U> shared_ptr<T> const_pointer_cast(shared_ptr<U> const& r);

> > Postconditions: If `w` is the return value, `w.get() == const_cast<T*>(r.get()) && w.use_count() == r.use_count()`.

Alberto Ganesh Barbati has written an alternative proposal where he suggests (among other things) that the casts be respecified in terms of the aliasing constructor as follows:

Change 20.3.2.2.10 [util.smartptr.shared.cast]:

> -2- Returns: If `r` is empty, an `empty shared_ptr<T>;` otherwise, a `shared_ptr<T>` object that stores `static_cast<T*>(r.get())` and shares ownership with `r`. `shared_ptr<T>(r, static_cast<T*>(r.get())`.

> -6- Returns:

> - When `dynamic_cast<T*>(r.get())` returns a nonzero value, a `shared_ptr<T>` object that stores a copy of it and shares ownership with `r`;
> - Otherwise, an empty `shared_ptr<T>` object.
> - If `p = dynamic_cast<T*>(r.get())` is a non-null pointer, `shared_ptr<T>(r, p);`
> - Otherwise, `shared_ptr<T>()`.

> -10- Returns: If `r` is empty, an `empty shared_ptr<T>;` otherwise, a `shared_ptr<T>` object that stores `const_cast<T*>(r.get())` and shares ownership with `r`. `shared_ptr<T>(r, const_cast<T*>(r.get())`.

This takes care of the missing postconditions for the casts by bringing in the aliasing constructor postcondition "by reference".