Reputation: 6410
It could be implemented thusly:
std::shared_ptr<T> operator->() {
auto shared = lock();
if(shared == nullptr) {
throw std::bad_weak_ptr(); // or some other exception
}
return shared;
}
Why did the authors of weak_ptr decide to not have operator->? (They must have thought of it)
I can think of potential reasons but I wonder what the official reason is, if one exists. Potential reasons:
If you are confused about the lifetime of the returned shared_ptr, see this paper.
Also, someone asked why would one use a weak_ptr if you expect it to not be expired? Answer: cycles.
Upvotes: 10
Views: 4337
Reputation: 17415
I'll take a shot at giving a good reason why this is not a good idea:
One thing is clarity:
ptr->foo();
ptr->bar();
The problem here is that somewhere between the first and second call, ptr might expire, either by a different thread (which would be a race condition) or by a sideeffect of the call to foo
.
Another thing is symmetry: When I have a pointer, I expect operators *
, ->
and an implicit conversion to a boolean value. Some might disagree, but operators *
and ->
often coincide. I'd be surprised that this isn't the case here.
That said, with C++11, it's just too easy to write:
if (auto p = ptr.lock()) {
p->foo();
p->bar();
}
Knowing that ptr
is a weak_ptr
, the meaning and behaviour of that code is pretty clear.
Upvotes: 7
Reputation: 490108
The original proposal weak_ptr
didn't include an overload of operator->
.
I haven't looked through the minutes of every meeting since, but have followed what's been discussed, and don't recall a mention of anybody having proposed that it should be added. As such, the "official" reason it's not present is probably largely that nobody's proposed that it be added.
If you want to go back to the very beginning, most of this stems from John Ellis and David Detlef's Safe, Efficient Garbage Collection for C++ paper, from Usenix 1994. That included a weakptr
type in its Appendix B. That's somewhat different (weakptr::pointer
returns a pointer directly, or a null-pointer if the pointee has already been destroyed), but still didn't use an operator overload to do the job.
Greg Colvin wrote the original proposal to add counted_ptr
to the standard. Its counted_ptr
was essentially equivalent to what's now called shared_ptr
, but did not include anything analogous to weak_ptr
.
Shortly after the committee rejected the counted_ptr
proposal and adopted auto_ptr
instead, the basic idea of counted_ptr
was revived on Boost. I don't remember seeing any discussion of adding an operator->
to it, but it "lived" there for so long that it's entirely possible somebody could have proposed it without my being aware of it.
Upvotes: 10