[util.smartptr.shared.cast]

# 20 Memory management library [[mem]](./#mem)

## 20.3 Smart pointers [[smartptr]](smartptr#util.smartptr.shared.cast)

### 20.3.2 Shared-ownership pointers [[util.sharedptr]](util.sharedptr#util.smartptr.shared.cast)

#### 20.3.2.2 Class template shared_ptr [[util.smartptr.shared]](util.smartptr.shared#cast)

#### 20.3.2.2.10 Casts [util.smartptr.shared.cast]

[ð](#lib:static_pointer_cast,shared_ptr)

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

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4677)

*Mandates*: The expression static_cast<T*>((U*)nullptr) is well-formed[.](#1.sentence-1)

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4681)

*Returns*: shared_ptr<T>(*R*, static_cast<typename shared_ptr<T>::element_type*>(r.get())) where *R* is r for the first overload, andstd​::​move(r) for the second[.](#2.sentence-1)

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4689)

[*Note [1](#note-1)*:

The seemingly equivalent expressionshared_ptr<T>(static_cast<T*>(r.get())) can result in undefined behavior, attempting to delete the
same object twice[.](#3.sentence-1)

â *end note*]

[ð](#lib:dynamic_pointer_cast,shared_ptr)

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

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4707)

*Mandates*: The expression dynamic_cast<T*>((U*)nullptr) is well-formed[.](#4.sentence-1)

The expression dynamic_cast<typename shared_ptr<T>​::​element_type*>(r.get()) is well-formed[.](#4.sentence-2)

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4712)

*Preconditions*: The expression dynamic_cast<typename shared_ptr<T>​::​element_type*>(r.get()) has well-defined behavior[.](#5.sentence-1)

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4716)

*Returns*: 

- [(6.1)](#6.1)

  When dynamic_cast<typename shared_ptr<T>​::​element_type*>(r.get()) returns a non-null value p, shared_ptr<T>(*R*, p),
 where *R* is r for the first overload, and std​::​move(r) for the second[.](#6.1.sentence-1)

- [(6.2)](#6.2)

  Otherwise, shared_ptr<T>()[.](#6.2.sentence-1)

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4727)

[*Note [2](#note-2)*:

The seemingly equivalent expressionshared_ptr<T>(dynamic_cast<T*>(r.get())) can result in
undefined behavior, attempting to delete the same object twice[.](#7.sentence-1)

â *end note*]

[ð](#lib:const_pointer_cast,shared_ptr)

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

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4744)

*Mandates*: The expression const_cast<T*>((U*)nullptr) is well-formed[.](#8.sentence-1)

[9](#9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4748)

*Returns*: shared_ptr<T>(*R*, const_cast<typename shared_ptr<T>::element_type*>(r.get())) where *R* is r for the first overload, andstd​::​move(r) for the second[.](#9.sentence-1)

[10](#10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4756)

[*Note [3](#note-3)*:

The seemingly equivalent expressionshared_ptr<T>(const_cast<T*>(r.get())) can result in
undefined behavior, attempting to delete the same object twice[.](#10.sentence-1)

â *end note*]

[ð](#lib:reinterpret_pointer_cast,shared_ptr)

`template<class T, class U>
  shared_ptr<T> reinterpret_pointer_cast(const shared_ptr<U>& r) noexcept;
template<class T, class U>
  shared_ptr<T> reinterpret_pointer_cast(shared_ptr<U>&& r) noexcept;
`

[11](#11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4773)

*Mandates*: The expression reinterpret_cast<T*>((U*)nullptr) is well-formed[.](#11.sentence-1)

[12](#12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4777)

*Returns*: shared_ptr<T>(*R*, reinterpret_cast<typename shared_ptr<T>::element_type*>(r.get())) where *R* is r for the first overload, andstd​::​move(r) for the second[.](#12.sentence-1)

[13](#13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4785)

[*Note [4](#note-4)*:

The seemingly equivalent expressionshared_ptr<T>(reinterpret_cast<T*>(r.get())) can result in
undefined behavior, attempting to delete the same object twice[.](#13.sentence-1)

â *end note*]
