Search code examples
c++setweak-ptr

Possible to create weak_ptr to set elements


I have a std::multiset of objects (created in place with set::emplace). This gives me sorted access using a custom comparator.

The objects themselves also contain a list of pointers to other objects that identify some dependencies (the dependencies are not used in the comparator and do not affect the underlying tree structure of the set). Currently this dependency list is implemented as an std::list of raw object pointers. This is unsafe, however, because a dependency could be removed from the multiset without the objects holding these dependency pointers being notified.

Is there a way to use weak_ptr to point to the objects in the set without using shared_ptrs in the set itself? Or is the only way to accomplish this to have a set of share_ptrs instead of Objects?


Solution

  • std::weak_ptr actually points to the metadata block that std::shared_ptr uses to track both the object location and lifetime. If there's no shared_ptr, there's no metadata block.

    It might be possible to design a weak pointer that doesn't rely on std::shared_ptr, but that would not be std::weak_ptr. The weak pointer and the container would have to cooperate at a very deep level -- you'd be replacing std::multiset, too.

    I believe you may have a larger problem, however... if you are removing things from the std::multiset, that may invalidate pointers to all elements, not just the ones removed. Storing std::shared_ptr inside your set would solve both these problems at once.

    Actually, struck out section doesn't apply to associative containers, including std::multiset. Other container types would not be safe. Multiset however guarantees that

    the erase members shall invalidate only iterators and references to the erased elements