Taylor
Taylor

Reputation: 6410

Why doesn't std::weak_ptr have operator->?

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;
  }

Live Demo

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

Answers (2)

Ulrich Eckhardt
Ulrich Eckhardt

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

Jerry Coffin
Jerry Coffin

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

Related Questions