namespace std { template<class T> class shared_ptr { public: using element_type = remove_extent_t<T>; using weak_type = weak_ptr<T>; // [util.smartptr.shared.const], constructors constexpr shared_ptr() noexcept; constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { } template<class Y> explicit shared_ptr(Y* p); template<class Y, class D> shared_ptr(Y* p, D d); template<class Y, class D, class A> shared_ptr(Y* p, D d, A a); template<class D> shared_ptr(nullptr_t p, D d); template<class D, class A> shared_ptr(nullptr_t p, D d, A a); template<class Y> shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept; template<class Y> shared_ptr(shared_ptr<Y>&& r, element_type* p) noexcept; shared_ptr(const shared_ptr& r) noexcept; template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept; shared_ptr(shared_ptr&& r) noexcept; template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept; template<class Y> explicit shared_ptr(const weak_ptr<Y>& r); template<class Y, class D> shared_ptr(unique_ptr<Y, D>&& r); // [util.smartptr.shared.dest], destructor ~shared_ptr(); // [util.smartptr.shared.assign], assignment shared_ptr& operator=(const shared_ptr& r) noexcept; template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept; shared_ptr& operator=(shared_ptr&& r) noexcept; template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r) noexcept; template<class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r); // [util.smartptr.shared.mod], modifiers void swap(shared_ptr& r) noexcept; void reset() noexcept; template<class Y> void reset(Y* p); template<class Y, class D> void reset(Y* p, D d); template<class Y, class D, class A> void reset(Y* p, D d, A a); // [util.smartptr.shared.obs], observers element_type* get() const noexcept; T& operator*() const noexcept; T* operator->() const noexcept; element_type& operator[](ptrdiff_t i) const; long use_count() const noexcept; explicit operator bool() const noexcept; template<class U> bool owner_before(const shared_ptr<U>& b) const noexcept; template<class U> bool owner_before(const weak_ptr<U>& b) const noexcept; }; template<class T> shared_ptr(weak_ptr<T>) -> shared_ptr<T>; template<class T, class D> shared_ptr(unique_ptr<T, D>) -> shared_ptr<T>; }
if (shared_ptr<X> px = dynamic_pointer_cast<X>(py)) { // do something with px }— end example
if (p != nullptr && p->weak_this.expired()) p->weak_this = shared_ptr<remove_cv_t<Y>>(*this, const_cast<remove_cv_t<Y>*>(p));
constexpr shared_ptr() noexcept;
template<class Y> explicit shared_ptr(Y* p);
template<class Y, class D> shared_ptr(Y* p, D d);
template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
template<class D> shared_ptr(nullptr_t p, D d);
template<class D, class A> shared_ptr(nullptr_t p, D d, A a);
template<class Y> shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
template<class Y> shared_ptr(shared_ptr<Y>&& r, element_type* p) noexcept;
shared_ptr(const shared_ptr& r) noexcept;
template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
shared_ptr(shared_ptr&& r) noexcept;
template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
template<class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
shared_ptr<int> p(new int); shared_ptr<void> q(p); p = p; q = p;both assignments may be no-ops.
shared_ptr& operator=(shared_ptr&& r) noexcept;
template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
template<class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);
void swap(shared_ptr& r) noexcept;
void reset() noexcept;
template<class Y> void reset(Y* p);
template<class Y, class D> void reset(Y* p, D d);
template<class Y, class D, class A> void reset(Y* p, D d, A a);
element_type* get() const noexcept;
T& operator*() const noexcept;
T* operator->() const noexcept;
element_type& operator[](ptrdiff_t i) const;
explicit operator bool() const noexcept;
template<class T, ...>
shared_ptr<T> make_shared(args);
template<class T, class A, ...>
shared_ptr<T> allocate_shared(const A& a, args);
template<class T, ...>
shared_ptr<T> make_shared_for_overwrite(args);
template<class T, class A, ...>
shared_ptr<T> allocate_shared_for_overwrite(const A& a, args);
template<class T, class... Args>
shared_ptr<T> make_shared(Args&&... args); // T is not array
template<class T, class A, class... Args>
shared_ptr<T> allocate_shared(const A& a, Args&&... args); // T is not array
template<class T> shared_ptr<T>
make_shared(size_t N); // T is U[]
template<class T, class A>
shared_ptr<T> allocate_shared(const A& a, size_t N); // T is U[]
template<class T>
shared_ptr<T> make_shared(); // T is U[N]
template<class T, class A>
shared_ptr<T> allocate_shared(const A& a); // T is U[N]
template<class T>
shared_ptr<T> make_shared(size_t N,
const remove_extent_t<T>& u); // T is U[]
template<class T, class A>
shared_ptr<T> allocate_shared(const A& a, size_t N,
const remove_extent_t<T>& u); // T is U[]
shared_ptr<double[]> p = make_shared<double[]>(1024, 1.0); // shared_ptr to a double[1024], where each element is 1.0 shared_ptr<double[][2]> q = make_shared<double[][2]>(6, {1.0, 0.0}); // shared_ptr to a double[6][2], where each double[2] element is {1.0, 0.0} shared_ptr<vector<int>[]> r = make_shared<vector<int>[]>(4, {1, 2}); // shared_ptr to a vector<int>[4], where each vector has contents {1, 2}— end example
template<class T>
shared_ptr<T> make_shared(const remove_extent_t<T>& u); // T is U[N]
template<class T, class A>
shared_ptr<T> allocate_shared(const A& a,
const remove_extent_t<T>& u); // T is U[N]
shared_ptr<double[1024]> p = make_shared<double[1024]>(1.0); // shared_ptr to a double[1024], where each element is 1.0 shared_ptr<double[6][2]> q = make_shared<double[6][2]>({1.0, 0.0}); // shared_ptr to a double[6][2], where each double[2] element is {1.0, 0.0} shared_ptr<vector<int>[4]> r = make_shared<vector<int>[4]>({1, 2}); // shared_ptr to a vector<int>[4], where each vector has contents {1, 2}— end example
template<class T>
shared_ptr<T> make_shared_for_overwrite();
template<class T, class A>
shared_ptr<T> allocate_shared_for_overwrite(const A& a);
struct X { double data[1024]; }; shared_ptr<X> p = make_shared_for_overwrite<X>(); // shared_ptr to a default-initialized X, where each element in X::data has an indeterminate value shared_ptr<double[1024]> q = make_shared_for_overwrite<double[1024]>(); // shared_ptr to a default-initialized double[1024], where each element has an indeterminate value— end example
template<class T>
shared_ptr<T> make_shared_for_overwrite(size_t N);
template<class T, class A>
shared_ptr<T> allocate_shared_for_overwrite(const A& a, size_t N);
template<class T, class U>
bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
template<class T>
bool operator==(const shared_ptr<T>& a, nullptr_t) noexcept;
template<class T, class U>
strong_ordering operator<=>(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
template<class T>
strong_ordering operator<=>(const shared_ptr<T>& a, nullptr_t) noexcept;
template<class T>
void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
template<class T, class U>
shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
template<class T, class U>
shared_ptr<T> static_pointer_cast(shared_ptr<U>&& r) noexcept;
template<class T, class U>
shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
template<class T, class U>
shared_ptr<T> dynamic_pointer_cast(shared_ptr<U>&& r) noexcept;
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;
template<class D, class T>
D* get_deleter(const shared_ptr<T>& p) noexcept;
template<class E, class T, class Y>
basic_ostream<E, T>& operator<<(basic_ostream<E, T>& os, const shared_ptr<Y>& p);