std::shared_ptr 删除器运行时,弱指针是否保证已过期?
Are weak pointers guaranteed to have expired by the time the std::shared_ptr deleter runs?
如果我有一个带有自定义删除器的 std::shared_ptr<Foo>
,是否可以保证所有关联的弱指针都被删除器视为已过期? (如果您能引用标准中的相关章节,我将不胜感激。)
换句话说,下面的断言是否保证不会触发?
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
的析构函数,规范只说:
- If
*this
is empty or shares ownership with another shared_ptr
instance (use_count()
> 1), there are no side effects.
- Otherwise, if
*this
owns an object p
and a deleter d
, d(p)
is called.
Otherwise, *this
owns a pointer p
, and delete p
is called.
[Note: Since the destruction of *this
decreases the number of instances that share ownership with *this by one, after *this
has been destroyed all shared_ptr
instances that shared ownership with *this
will report a use_count()
that is one less than its previous value. —end note ]
而 reset
的定义是将 shared_ptr
交换为临时对象,然后将其销毁。
所以规范只保证 use_count
的状态在 析构函数完成后将为零 。未指定在该过程中将其设置为 0 的确切时间。
C++14 标准中显然没有任何内容可以保证这一点。我现在已经为涵盖该问题的标准打开了 defect report。
如果我有一个带有自定义删除器的 std::shared_ptr<Foo>
,是否可以保证所有关联的弱指针都被删除器视为已过期? (如果您能引用标准中的相关章节,我将不胜感激。)
换句话说,下面的断言是否保证不会触发?
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
的析构函数,规范只说:
- If
*this
is empty or shares ownership with anothershared_ptr
instance (use_count()
> 1), there are no side effects.- Otherwise, if
*this
owns an objectp
and a deleterd
,d(p)
is called.Otherwise,
*this
owns a pointerp
, and deletep
is called.[Note: Since the destruction of
*this
decreases the number of instances that share ownership with *this by one, after*this
has been destroyed allshared_ptr
instances that shared ownership with*this
will report ause_count()
that is one less than its previous value. —end note ]
而 reset
的定义是将 shared_ptr
交换为临时对象,然后将其销毁。
所以规范只保证 use_count
的状态在 析构函数完成后将为零 。未指定在该过程中将其设置为 0 的确切时间。
C++14 标准中显然没有任何内容可以保证这一点。我现在已经为涵盖该问题的标准打开了 defect report。