# weak_ptr class template

The weak_ptr class template stores a "weak reference" to an object that's already managed by a shared_ptr. To access the object, a weak_ptr can be converted to a shared_ptr using the shared_ptr constructor or the function make_shared. When the last shared_ptr to the object goes away and the object is deleted, the attempt to obtain a shared_ptr from the weak_ptr instances that refer to the deleted object will fail: the constructor will throw an exception of type boost::use_count_is_zero, and make_shared will return a default constructed (null) shared_ptr.

Every weak_ptr meets the CopyConstructible and Assignable requirements of the C++ Standard Library, and so can be used in standard library containers. Comparison operators are supplied so that weak_ptr works with the standard library's associative containers.

The class template is parameterized on T, the type of the object pointed to. T must meet the smart pointer common requirements.

Compared to shared_ptr, weak_ptr provides a very limited subset of operations since accessing its stored pointer is often dangerous in multithreaded programs, and sometimes unsafe even within a single thread (that is, it may invoke undefined behavior.) Consider, for example, this innocent piece of code:

    shared_ptr<int> p(new int(5));
    weak_ptr<int> q(p);

    // some time later

    if(int * r = q.get())
    {
        // use *r
    }

Imagine that after the if, but immediately before r is used, another thread executes the statement `p.reset()`. Now r is a dangling pointer.

The solution to this problem is to create a temporary shared_ptr from q:

    shared_ptr<int> p(new int(5));
    weak_ptr<int> q(p);

    // some time later

    if(shared_ptr<int> r = make_shared(q))
    {
        // use *r
    }

Now r holds a reference to the object that was pointed by q. Even if `p.reset()` is executed in another thread, the object will stay alive until r goes out of scope (or is reset.)

## Synopsis

    namespace boost {

      template<typename T> class weak_ptr {

        public:
          typedef T element_type;

          weak_ptr();
          template<typename Y> weak_ptr(shared_ptr<Y> const & r); // never throws
          ~weak_ptr(); // never throws

          weak_ptr(weak_ptr const & r); // never throws
          template<typename Y> weak_ptr(weak_ptr<Y> const & r); // never throws

          weak_ptr & operator=(weak_ptr const & r); // never throws
          template<typename Y> weak_ptr & operator=(weak_ptr<Y> const & r); // never throws
          template<typename Y> weak_ptr & operator=(shared_ptr<Y> const & r); // never throws

          void reset();
          T * get() const; // never throws; deprecated, will disappear

          long use_count() const; // never throws
          bool expired() const; // never throws

          void swap(weak_ptr<T> & b); // never throws
      };

      template<typename T, typename U>
        bool operator==(weak_ptr<T> const & a, weak_ptr<U> const & b); // never throws
      template<typename T, typename U>
        bool operator!=(weak_ptr<T> const & a, weak_ptr<U> const & b); // never throws
      template<typename T>
        bool operator<(weak_ptr<T> const & a, weak_ptr<T> const & b); // never throws

      template<typename T> void swap(weak_ptr<T> & a, weak_ptr<T> & b); // never throws

      template<typename T>
        shared_ptr<T> make_shared(weak_ptr<T> const & r); // never throws

    }

## Members

### element_type

    typedef T element_type;

> Provides the type of the template parameter T.

### constructors

     weak_ptr();

> Effects: Constructs a weak_ptr.

> Postconditions: use count is 0; the stored pointer is 0.

> Throws: std::bad_alloc.

> Exception safety: If an exception is thrown, the constructor has no effect.

> Notes: T need not be a complete type. See the smart pointer common requirements.

    template<typename Y> weak_ptr(shared_ptr<Y> const & r); // never throws

> Effects: Constructs a weak_ptr, as if by storing a copy of the pointer stored in r.

> Throws: nothing.

> Notes: The use count for all copies is unchanged. When the last shared_ptr is destroyed, the use count and stored pointer become 0.

    weak_ptr(weak_ptr const & r); // never throws
    template<typename Y> weak_ptr(weak_ptr<Y> const & r); // never throws

> Effects: Constructs a weak_ptr, as if by storing a copy of the pointer stored in r.

> Throws: nothing.

> Notes: The use count for all copies is unchanged.

### destructor

    ~weak_ptr(); // never throws

> Effects: Destroys this weak_ptr but has no effect on the object its stored pointer points to.

> Throws: nothing.

> Notes: T need not be a complete type. See the smart pointer common requirements.

### assignment

    weak_ptr & operator=(weak_ptr const & r); // never throws
    template<typename Y> weak_ptr & operator=(weak_ptr<Y> const & r); // never throws
    template<typename Y> weak_ptr & operator=(shared_ptr<Y> const & r); // never throws

> Effects: Equivalent to `weak_ptr(r).swap(*this)`.

> Throws: nothing.

> Notes: The implementation is free to meet the effects (and the implied guarantees) via different means, without creating a temporary.

### reset

    void reset();

> Effects: Equivalent to `weak_ptr().swap(*this)`.

### get

    T * get() const; // never throws

> Returns: the stored pointer (0 if all shared_ptr objects for that pointer are destroyed.)

> Throws: nothing.

> Notes: Using get in multithreaded code is dangerous. After the function returns, the pointed-to object may be destroyed by a different thread, since the weak_ptr doesn't affect its use_count.

[get is very error-prone. Even single-threaded code may experience problems, as the returned pointer may be invalidated at any time, for example, indirectly by a member function of the pointee.

get is deprecated, and it will disappear in a future release. Do not use it.]

### use_count

    long use_count() const; // never throws

> Returns: the number of shared_ptr objects sharing ownership of the stored pointer.

> Throws: nothing.

> Notes: `use_count()` is not necessarily efficient. Use only for debugging and testing purposes, not for production code. T need not be a complete type. See the smart pointer common requirements.

### expired

    bool expired() const; // never throws

> Returns: `use_count() == 0`.

> Throws: nothing.

> Notes: `expired()` may be faster than `use_count()`. T need not be a complete type. See the smart pointer common requirements.

### swap

    void swap(weak_ptr & b); // never throws

> Effects: Exchanges the contents of the two smart pointers.

> Throws: nothing.

> Notes: T need not be a complete type. See the smart pointer common requirements.

## Free Functions

### comparison

    template<typename T, typename U>
      bool operator==(weak_ptr<T> const & a, weak_ptr<U> const & b); // never throws
    template<typename T, typename U>
      bool operator!=(weak_ptr<T> const & a, weak_ptr<U> const & b); // never throws

> Returns: `a.get() == b.get()`.

> Throws: nothing.

> Notes: T need not be a complete type. See the smart pointer common requirements.

    template<typename T>
      bool operator<(weak_ptr<T> const & a, weak_ptr<T> const & b); // never throws

> Returns: an implementation-defined value such that operator< is a strict weak ordering as described in section 25.3 `[lib.alg.sorting]` of the C++ standard.

> Throws: nothing.

> Notes: Allows weak_ptr objects to be used as keys in associative containers. T need not be a complete type. See the smart pointer common requirements.

### swap

    template<typename T>
      void swap(weak_ptr<T> & a, weak_ptr<T> & b) // never throws

> Effects: Equivalent to `a.swap(b)`.

> Throws: nothing.

> Notes: Matches the interface of std::swap. Provided as an aid to generic programming.

### make_shared

    template<typename T>
      shared_ptr<T> make_shared(weak_ptr<T> & const r) // never throws

> Returns: `r.expired()? shared_ptr<T>(): shared_ptr<T>(r)`.

> Throws: nothing.

[The current implementation of make_shared can propagate an exception thrown by the shared_ptr default constructor, so it doesn't meet the stated requirements. In a future release, this default constructor will not throw.]

Revised 29 August 2002

Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. Copyright 2002 Peter Dimov. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This document is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose.