弱指针是否保证在std::shared_ptr删除程序运行时已过期

Are weak pointers guaranteed to have expired by the time the std::shared_ptr deleter runs?

本文关键字:ptr 删除程序 运行时 过期 shared 是否 std 指针      更新时间:2023-10-16

如果我有一个带有自定义deleter的std::shared_ptr<Foo>,是否保证所有关联的弱指针都被deleter视为过期?(如果你能引用标准中的相关章节,我将不胜感激。)

换句话说,下面的断言是否保证不会开火?

std::weak_ptr<Foo> weak;
std::shared_ptr<Foo> strong{
  new Foo,
  [&weak] (Foo* f) {
    assert(weak.expired());
    delete f;
  },
};
weak = strong;
strong.reset();

该标准没有任何保证。对于shared_ptr的析构函数,规范只说:

  • 如果*this为空或与另一个shared_ptr实例共享所有权(use_count()>1),则没有副作用
  • 否则,如果*this拥有对象p和删除器d,则调用d(p)
  • 否则,*this拥有一个指针p,并调用delete p

    [注意:由于*this的销毁使与*this共享所有权的实例数量减少了一个,因此在*this被销毁后,所有与*this共享所有权的shared_ptr实例都将报告比其先前值少一个的use_count()。--结束注释]

reset的定义是将shared_ptr交换为临时的,然后将其销毁。

因此,规范只保证在析构函数结束后,use_count的状态将为零。在该过程中,没有指定将其设置为0的确切时间。

C++14标准中显然没有任何东西可以保证这一点。我现在已经打开了一份包含该问题的标准的缺陷报告。