
Hi, a weak_ptr can be said to have three states. 1. Never been assigned to (default constructed) 2. Assigned to, lock will return a shared_ptr to a valid object. 3. Assigned to, but the object pointed to is dead and lock will return null. As far as I know it is currently impossible to distinguish between case 1 and 3. Am I overlooking something? If not, can somebody explain the reason why it is not possible to distinguish the two cases? Admittedly, I cannot come up with any elegant design in which such a distinction is useful, so the question is merely theoretical. Thanks, Jaap Suter

Jaap Suter wrote:
Hi,
a weak_ptr can be said to have three states.
1. Never been assigned to (default constructed) 2. Assigned to, lock will return a shared_ptr to a valid object. 3. Assigned to, but the object pointed to is dead and lock will return null.
As far as I know it is currently impossible to distinguish between case 1 and 3. Am I overlooking something? If not, can somebody explain the reason why it is not possible to distinguish the two cases? Admittedly, I cannot come up with any elegant design in which such a distinction is useful, so the question is merely theoretical.
There is no particular reason to make 1 and 3 indistinguishable. You are right that weak_ptr could have provided an "is empty" query in addition to expired(). There just aren't any compelling use cases for it, as far as I know.

"Jaap Suter" <boost@jaapsuter.com> wrote in message news:003501c58833$f508a020$4119059a@unknown...
Hi,
a weak_ptr can be said to have three states.
1. Never been assigned to (default constructed) 2. Assigned to, lock will return a shared_ptr to a valid object. 3. Assigned to, but the object pointed to is dead and lock will return null.
As far as I know it is currently impossible to distinguish between case 1 and 3. Am I overlooking something? If not, can somebody explain the reason why it is not possible to distinguish the two cases? Admittedly, I cannot come up with any elegant design in which such a distinction is useful, so the question is merely theoretical.
Actually, it is possible to distinguish case 1 from case 3: weak_ptr<Foo> wp = get_weak_ptr(); if (wp.expired()) { weak_ptr emptyPtr; // Default constructed weak_ptr if (!(emptyPtr < wp) && !(wp < emptyPtr)) { cout << "Case 1" << endl } else { cout << "Case 3" << endl; } } else { // Not expired cout << "Case 2" << endl; } } It is vital that a weak_ptr that is put into a set and later expires does not change its ordering relative to the other elements of the set. Joe Gottman

Joe Gottman wrote:
Actually, it is possible to distinguish case 1 from case 3:
weak_ptr<Foo> wp = get_weak_ptr(); if (wp.expired()) { weak_ptr emptyPtr; // Default constructed weak_ptr if (!(emptyPtr < wp) && !(wp < emptyPtr)) {
Right... you can thank Joe for that, with the latest changes to TR1 (*) operator< can tell you whether a weak_ptr is empty. The original version did not guarantee that all empty weak pointers compared equivalent. :-) So it's possible. template<class T> bool is_empty( weak_ptr<T> const & wp ) { weak_ptr<T> empty; return !(empty < wp) && !(wp < empty); } Whether it should be used is another story. :-) (*) See issue 2.4 in http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1837.pdf

"Peter Dimov" <pdimov@mmltd.net> wrote in message news:006c01c588dc$8325c380$6501a8c0@pdimov2...
Right... you can thank Joe for that, with the latest changes to TR1 (*) operator< can tell you whether a weak_ptr is empty. The original version did not guarantee that all empty weak pointers compared equivalent. :-)
I just checked the documentation for operator<() for shared_ptr and weak_ptr, and it says two shared_ptrs (or weak_ptrs) are equivalent if and only if they share ownership. You should probably add "or are both empty". Joe Gottman
participants (4)
-
Jaap Suter
-
Joe Gottman
-
Pavel Vozenilek
-
Peter Dimov