简体   繁体   English

为什么std :: weak_ptr没有operator->?

[英]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->? 为什么weak_ptr的作者决定不使用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: 可能的原因:

  • Discourage extra increment/decrement of reference count for multiple calls 阻止多次调用的额外递增/递减引用计数
  • Encourage explicit locking rather than (somewhat hidden) exceptions 鼓励显式锁定而不是(有些隐藏)异常

If you are confused about the lifetime of the returned shared_ptr, see this paper. 如果您对返回的shared_ptr的生命周期感到困惑,请参阅此文章。

Also, someone asked why would one use a weak_ptr if you expect it to not be expired? 另外,有人问为什么如果你期望它没有过期,会使用weak_ptr? Answer: cycles. 答案:周期。

The original proposal weak_ptr didn't include an overload of operator-> . 最初的提议 weak_ptr没有包含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. 如果你想回到开始,这个最源于约翰·埃利斯和大卫德特勒夫的安全,高效的垃圾收集C ++纸,从Usenix的1994年,其中包括一个weakptr在其附录B型这是有些不同( weakptr::pointer直接返回一个指针,如果指针对象已经被销毁,则返回一个空指针),但仍然没有使用运算符重载来完成这项工作。

Greg Colvin wrote the original proposal to add counted_ptr to the standard. counted_ptr文写了最初的提议,将counted_ptr添加到标准中。 Its counted_ptr was essentially equivalent to what's now called shared_ptr , but did not include anything analogous to weak_ptr . 它的counted_ptr基本上等同于现在称为shared_ptr东西,但没有包含类似于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. 不久后,委员会拒绝了counted_ptr建议,并接受auto_ptr替代,基本思路counted_ptr复兴的推动作用。 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. 我不记得看过任何关于添加一个operator->讨论,但是它“存活”了很长时间以至于完全有可能有人在没有意识到它的情况下提出它。

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 . 这里的问题是在第一次和第二次调用之间的某个地方,ptr可能会通过一个不同的线程(这将是一个竞争条件)或者对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: 也就是说,使用C ++ 11,它很容易编写:

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. 知道ptr是一个weak_ptr ,该代码的含义和行为非常清楚。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM