2315. weak_ptr should be movable

Section: 23.11.4 [util.smartptr.weak] Status: C++14 Submitter: Stephan T. Lavavej Opened: 2013-09-21 Last modified: 2016-02-10

Priority: 2

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

View all issues with C++14 status.

Discussion:

Like shared_ptr, weak_ptr should be movable to avoid unnecessary atomic increments/decrements of the weak refcount.

[2014-02-13 Issaquah: Move to Immediate]

Proposed resolution:

This wording is relative to N3691.

  1. Edit 23.11.4 [util.smartptr.weak]/1, class template weak_ptr synopsis, as indicated:

    namespace std {
      template<class T> class weak_ptr {
      public:
        typedef T element_type;
    
        // 20.9.2.3.1, constructors
        constexpr weak_ptr() noexcept;
        template<class Y> weak_ptr(shared_ptr<Y> const& r) noexcept;
        weak_ptr(weak_ptr const& r) noexcept;
        template<class Y> weak_ptr(weak_ptr<Y> const& r) noexcept;
        weak_ptr(weak_ptr&& r) noexcept;
        template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept;
    
        […]
    
        // 20.9.2.3.3, assignment
        weak_ptr& operator=(weak_ptr const& r) noexcept;
        template<class Y> weak_ptr& operator=(weak_ptr<Y> const& r) noexcept;
        template<class Y> weak_ptr& operator=(shared_ptr<Y> const& r) noexcept;
        weak_ptr& operator=(weak_ptr&& r) noexcept;
        template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;
      };
    }
    
  2. Add the following new paragraphs at the end of sub-clause 23.11.4.1 [util.smartptr.weak.const]:

    weak_ptr(weak_ptr&& r) noexcept;
    template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept;
    

    -?- Remark: The second constructor shall not participate in overload resolution unless Y* is implicitly convertible to T*.

    -?- Effects: Move-constructs a weak_ptr instance from r.

    -?- Postconditions: *this shall contain the old value of r. r shall be empty. r.use_count() == 0.

  3. Edit 23.11.4.3 [util.smartptr.weak.assign] as indicated:

    weak_ptr& operator=(const weak_ptr& r) noexcept;
    template<class Y> weak_ptr& operator=(const weak_ptr<Y>& r) noexcept;
    template<class Y> weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;
    

    -1- Effects: […]

    -2- Remarks: […]

    -?- Returns: *this.

    weak_ptr& operator=(weak_ptr&& r) noexcept;
    template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;
    

    -?- Effects: Equivalent to weak_ptr(std::move(r)).swap(*this).

    -?- Returns: *this.