请考虑我的经验不足,但我不了解std::owner_less
的要点。
我一直shown不建议使用以map
作为键的weak_ptr
,因为过期的weak_ptr
键会破坏 map ,实际上:
该行为的不确定性如何?我问的原因是因为docs谈到了owner_less
:
再次,这是我的经验不足,但听起来expired map
不会完全破坏weak_ptr
:
听起来它可能比完全未定义的要宽松。如果一个人的实现删除了过期的weak_ptrs,并且根本没有使用或没有任何余地,那么行为何时会变得不确定?
如果一个人的实现不考虑顺序,而只需要一种方便的方法来将weak_ptr
与数据相关联,该行为是否仍未定义?换句话说,find
将开始返回错误的 key 吗?
map
我可以在文档中找到的唯一问题是上面提到的内容,过期的weak_ptrs将返回等效值。
根据这些docs,对于不依赖于排序也不使用过期weak_ptr
的实现,这不是问题:
这听起来像是如果实现不关心顺序,也没有使用过期的weak_ptr
,那么就没有问题,因为值是由键而不是按顺序引用的,因此,过期的find
的weak_ptr
可能会返回另一个weak_ptr
的值,但是由于存在在这个特定的实现中,除了使用erase
d,没有其他用途,没有问题。
我可以看到,无论使用哪种应用程序,如何都需要使用weak_ptr
排序或过期的weak_ptr
可能是个问题,但是所有行为似乎都未定义,因此map
或set
似乎并没有完全被过期的weak_ptr
破坏。
是否有更多关于map
,weak_ptr
和owner_less
的技术性解释来驳斥这些文档和我的解释?
最佳答案
需要澄清的一点。使用owner_less时过期的weak_ptr不是UB。从标准
要记住的一件事是,一个空的weak_ptr是从未分配过有效的shared_ptr的,或者是被分配了一个空shared_ptr/weak_ptr的。已经到期的weak_ptr不是空的weak_ptr。
编辑:
上面的定义取决于拥有“空” weak_ptr的含义。那么,让我们看一下标准
交换只是交换内容,分配被定义为上述构造函数加上交换。
要创建一个空的weak_ptr
,您可以使用默认的构造函数,或者向其传递一个为空的weak_ptr或shared_ptr。现在,您会注意到到期实际上并不会导致weak_ptr为空。它只是使它的use_count()
为零,而expired()
返回true。这是因为在共享对象的所有弱指针也都被释放之前,无法释放基础引用计数。