请考虑我的经验不足,但我不了解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,那么就没有问题,因为值是由键而不是按顺序引用的,因此,过期的findweak_ptr可能会返回另一个weak_ptr的值,但是由于存在在这个特定的实现中,除了使用erase d,没有其他用途,没有问题。
我可以看到,无论使用哪种应用程序,如何都需要使用weak_ptr排序或过期的weak_ptr可能是个问题,但是所有行为似乎都未定义,因此mapset似乎并没有完全被过期的weak_ptr破坏。
是否有更多关于mapweak_ptrowner_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。这是因为在共享对象的所有弱指针也都被释放之前,无法释放基础引用计数。

07-27 13:38