Created on 2019-03-15.00:00:00 last changed 12 months ago
Proposed resolution:
This wording is relative to N4849.
Modify [util.smartptr.weak.const] as indicated:
constexpr weak_ptr() noexcept;-1- Effects: Constructs an empty weak_ptr object that stores a null pointer value.
-2- Postconditions: use_count() == 0.weak_ptr(const weak_ptr& r) noexcept; template<class Y> weak_ptr(const weak_ptr<Y>& r) noexcept; template<class Y> weak_ptr(const shared_ptr<Y>& r) noexcept;-3- Remarks: The second and third constructors shall not participate in overload resolution unless Y* is compatible with T*.
-4- Effects: If r is empty, constructs an empty weak_ptr object that stores a null pointer value; otherwise, constructs a weak_ptr object that shares ownership with r and stores a copy of the pointer stored in r. -5- Postconditions: use_count() == r.use_count().weak_ptr(weak_ptr&& r) noexcept; template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept;-6- Remarks: The second constructor shall not participate in overload resolution unless Y* is compatible with T*.
-7- Effects: Move constructs a weak_ptr instance from r. -8- Postconditions: *thisshall containcontains the old value of r. rshall beis empty., stores a null pointer value, and r.use_count() == 0.
[ 2020-11-09 Approved In November virtual meeting. Status changed: Ready → WP. ]
[ 2020-02-16; Prague ]
Reviewed revised wording and moved to Ready for Varna.
[ 2020-02-14 Casey updates P/R per LWG instruction ]
While reviewing the P/R in Prague, Tim Song noticed that the stored pointer value of a moved-from weak_ptr must also be specified.[ 2019-06-09 Priority set to 2 after reflector discussion ]
Previous resolution [SUPERSEDED]
This wording is relative to N4810.
Modify [util.smartptr.weak.const] as indicated (note the drive-by edit to cleanup the occurrences of "constructs an object of class foo"):
constexpr weak_ptr() noexcept;-1- Effects: Constructs an empty
-2- Ensures: use_count() == 0.weak_ptrobject that stores a null pointer value.weak_ptr(const weak_ptr& r) noexcept; template<class Y> weak_ptr(const weak_ptr<Y>& r) noexcept; template<class Y> weak_ptr(const shared_ptr<Y>& r) noexcept;-3- Remarks: The second and third constructors shall not participate in overload resolution unless Y* is compatible with T*.
-4- Effects: If r is empty, constructs an emptyweak_ptrobject that stores a null pointer value; otherwise, constructs a weak_ptr object that shares ownership with r and stores a copy of the pointer stored in r. -5- Ensures: use_count() == r.use_count().
[util.smartptr.weak.const] specifies weak_ptr's default constructor:
constexpr weak_ptr() noexcept;1 Effects: Constructs an empty weak_ptr object.
2 Ensures: use_count() == 0.
and shared_ptr converting constructor template:
weak_ptr(const weak_ptr& r) noexcept; template<class Y> weak_ptr(const weak_ptr<Y>& r) noexcept; template<class Y> weak_ptr(const shared_ptr<Y>& r) noexcept;3 Remarks: The second and third constructors shall not participate in overload resolution unless Y* is compatible with T*.
4 Effects: If r is empty, constructs an empty weak_ptr object; otherwise, constructs a weak_ptr object that shares ownership with r and stores a copy of the pointer stored in r. 5 Ensures: use_count() == r.use_count().
Note that neither specifies the value of the stored pointer when the resulting weak_ptr is empty. This didn't matter — the stored pointer value was unobservable for an empty weak_ptr — until we added atomic<weak_ptr>. [util.smartptr.atomic.weak]/15 says:
Remarks: Two weak_ptr objects are equivalent if they store the same pointer value and either share ownership, or both are empty. The weak form may fail spuriously. See [atomics.types.operations].
Two empty weak_ptr objects that store different pointer values are not equivalent. We could correct this by changing [util.smartptr.atomic.weak]/15 to "Two weak_ptr objects are equivalent if they are both empty, or if they share ownership and store the same pointer value." In practice, an implementation of atomic<weak_ptr> will CAS on both the ownership (control block pointer) and stored pointer value, so it seems cleaner to pin down the stored pointer value of an empty weak_ptr.
History | |||
---|---|---|---|
Date | User | Action | Args |
2023-11-22 15:47:43 | admin | set | status: wp -> c++23 |
2020-11-09 20:31:48 | admin | set | messages: + msg11542 |
2020-11-09 20:31:48 | admin | set | status: ready -> wp |
2020-07-17 22:37:26 | admin | set | messages: + msg11372 |
2020-07-17 22:37:26 | admin | set | status: new -> ready |
2020-02-14 10:56:19 | admin | set | messages: + msg11111 |
2019-06-10 05:16:56 | admin | set | messages: + msg10430 |
2019-03-16 15:30:52 | admin | set | messages: + msg10356 |
2019-03-15 00:00:00 | admin | create |