This paper proposes a resolution to C++17 CD comment CA 14, which identified
issues with use_count and unique in shared_ptr.
1. CA 14
The removal of the "debug only" restriction foruse_countanduniqueinshared_ptrintroduced a bug: in order foruniqueto produce a useful and reliable value, it needs a synchronize clause to ensure that prior accesses through another reference are visible to the successful caller ofunique. Many current implementations use a relaxed load, and do not provide this guarantee, since it’s not stated in the Standard. For debug/hint usage that was OK. Without it the specification is unclear and misleading.
2. Proposed Wording
The proposed changes are relative to [N4604], the Committee Draft for C++17.
The � character is used to denote a placeholder number which the editor shall determine.
2.1. Part A
Change 20.11.2.2.5 [util.smartptr.shared.obs] as depicted:
long use_count() const noexcept;
-7- Returns: The number ofshared_ptrobjects,*thisincluded, that share ownership with*this, or 0 when*thisis empty. -�- Synchronization: None.-�- [ Note:
get() == nullptrdoes not imply a specific return value ofuse_count(). — end note ]-�- [ Note:
weak_ptr<T>::lock()can affect the return value ofuse_count(). — end note ]-�- [ Note: When multiple threads can affect the return value of
use_count(), the result should be treated as approximate. In particular,use_count() == 1does not imply that accesses through a previously destroyedshared_ptrhave in any sense completed. — end note ]
bool unique() const noexcept;
-8- Returns:use_count() == 1.-9- [ Note: If you are usingunique()to implement copy on write, do not rely on a specific value whenget() == nullptr. — end note ]
2.2. Part B
Change 20.11.2.2 [util.smartptr.shared]/1 as depicted:
namespace std { template<class T> class shared_ptr { public: [...] long use_count() const noexcept;bool unique() const noexcept;; explicit operator bool() const noexcept; [...] }; [...] } // namespace std
Change 20.11.2.2.5 [util.smartptr.shared.obs] as depicted:
bool unique() const noexcept;
-8- Returns: use_count() == 1.
Add a new section:
D.� Deprecatedshared_ptrobservers [depr.util.smartptr.shared.obs]The following member is defined in addition to those specified in [util.smartptr.shared]:
namespace std { template<class T> class shared_ptr { public: bool unique() const noexcept; }; }
bool unique() const noexcept;
Returns: use_count() == 1.