This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of CD1 status.
Section: 19.11.3 [util.smartptr.shared] Status: CD1 Submitter: Matt Austern Opened: 2008-02-26 Last modified: 2016-02-10
Priority: Not Prioritized
View other active issues in [util.smartptr.shared].
View all other issues in [util.smartptr.shared].
View all issues with CD1 status.
Several places in 19.11.3 [util.smartptr.shared] refer to an "empty" shared_ptr. However, that term is nowhere defined. The closest thing we have to a definition is that the default constructor creates an empty shared_ptr and that a copy of a default-constructed shared_ptr is empty. Are any other shared_ptrs empty? For example, is shared_ptr((T*) 0) empty? What are the properties of an empty shared_ptr? We should either clarify this term or stop using it.
One reason it's not good enough to leave this term up to the reader's intuition is that, in light of N2351 and issue 711, most readers' intuitive understanding is likely to be wrong. Intuitively one might expect that an empty shared_ptr is one that doesn't store a pointer, but, whatever the definition is, that isn't it.
[ Peter adds: ]
Or, what is an "empty" shared_ptr?
Are any other shared_ptrs empty?
Yes. Whether a given shared_ptr instance is empty or not is (*) completely specified by the last mutating operation on that instance. Give me an example and I'll tell you whether the shared_ptr is empty or not.
(*) If it isn't, this is a legitimate defect.
For example, is shared_ptr((T*) 0) empty?
No. If it were empty, it would have a use_count() of 0, whereas it is specified to have an use_count() of 1.
What are the properties of an empty shared_ptr?
The properties of an empty shared_ptr can be derived from the specification. One example is that its destructor is a no-op. Another is that its use_count() returns 0. I can enumerate the full list if you really like.
We should either clarify this term or stop using it.
I don't agree with the imperative tone
A clarification would be either a no-op - if it doesn't contradict the existing wording - or a big mistake if it does.
I agree that a clarification that is formally a no-op may add value.
However, that term is nowhere defined.
Terms can be useful without a definition. Consider the following simplistic example. We have a type X with the following operations defined:X x; X x2(x); X f(X x); X g(X x1, X x2);
A default-constructed value is green.
A copy has the same color as the original.
f(x) returns a red value if the argument is green, a green value otherwise.
g(x1,x2) returns a green value if the arguments are of the same color, a red value otherwise.
Given these definitions, you can determine the color of every instance of type X, even if you have absolutely no idea what green and red mean.
Green and red are "nowhere defined" and completely defined at the same time.
Alisdair's wording is fine.
Append the following sentance to 19.11.3 [util.smartptr.shared]
shared_ptrclass template stores a pointer, usually obtained via
shared_ptrimplements semantics of shared ownership; the last remaining owner of the pointer is responsible for destroying the object, or otherwise releasing the resources associated with the stored pointer.