C++ 可以创建弱ptr来设置元素

C++ 可以创建弱ptr来设置元素,c++,set,weak-ptr,C++,Set,Weak Ptr,我有一个std::multiset对象(使用set::emplace就地创建)。这使我能够使用自定义比较器进行排序访问 对象本身还包含指向其他对象的指针列表,这些对象标识一些依赖项(这些依赖项不在比较器中使用,也不影响集合的底层树结构)。目前,此依赖项列表实现为原始对象指针的std::列表。但是,这是不安全的,因为可以在不通知包含这些依赖项指针的对象的情况下从multiset中删除依赖项 有没有一种方法可以使用弱\u ptr指向集合中的对象,而不使用集合本身中的共享\u ptr?或者,实现这一点

我有一个std::multiset对象(使用set::emplace就地创建)。这使我能够使用自定义比较器进行排序访问

对象本身还包含指向其他对象的指针列表,这些对象标识一些依赖项(这些依赖项不在比较器中使用,也不影响集合的底层树结构)。目前,此依赖项列表实现为原始对象指针的std::列表。但是,这是不安全的,因为可以在不通知包含这些依赖项指针的对象的情况下从multiset中删除依赖项


有没有一种方法可以使用弱\u ptr指向集合中的对象,而不使用集合本身中的共享\u ptr?或者,实现这一点的唯一方法是使用一组共享ptr而不是对象?

std::weak\u ptr
实际上指向
std::shared\u ptr
用于跟踪对象位置和生存期的元数据块。如果没有
共享\u ptr
,则没有元数据块

可以设计一个不依赖于
std::shared_ptr
的弱指针,但它不是
std::弱_ptr
。弱指针和容器必须在一个非常深层次上进行合作——您也将替换
std::multiset

我相信你可能有更大的问题,但是。。。如果要从
std::multiset
中删除内容,则可能会使指向所有元素的指针无效,而不仅仅是那些已删除的元素。将
std::shared_ptr
存储在您的设备中可以同时解决这两个问题

实际上,删除部分不适用于关联容器,包括
std::multiset
。其他容器类型将不安全。然而,Multiset保证

擦除
成员应仅使迭代器和对已擦除元素的引用无效


如果要使用智能指针来管理指针,则应使用智能指针来管理对该指针的所有访问,否则您仍然会遇到同样的问题。

能否将“已删除”对象移动到单独的容器中(而不是将其删除),并将其标记为“已删除”直到你可以更新树中的指针?这很有趣;看起来我必须使用C++17 set::extract。我看到的唯一问题是,我不知道(不迭代整个树)在单独的容器中何时不再有对该项的引用。这看起来就像扫描整个树并删除指向已删除对象的任何指针一样多。我认为仅仅使用共享的ptr可能更容易。我想你也可以给你的对象添加一个引用计数,当你遇到一个指向“已删除”对象的指针时,减少引用计数并删除指针。它更复杂,但
共享\u ptr
对性能有影响,因此这取决于您是否需要更简单的实现或更快的操作。
弱\u ptr
的唯一用途是将其升级为
共享\u ptr
(如果它有效;否则,您将得到null或异常),因此,虽然
共享ptr
接口可以在不支持
弱ptr
的情况下单独实现,但是
弱ptr
接口不能单独实现。您只能执行
弱\u ptr
->
共享\u ptr
->
T*
。而且,只要保持
共享,\u ptr
,就只能继续使用原始指针。试图从一个弱智能指针上切下中间人并获得一个原始指针不会产生一个可用的指针。@curiousguy,我的想法更倾向于
弱ptr->共享ptr
(实际上不需要获得原始指针)。我不明白的是,引用计数机制只存在于
共享ptr
中,因此,如果集合中没有
共享ptr
作为底层元素,那么就无法获得
弱ptr
(如下面Ben Voigt所解释的)。