Remove from a std::set<shared_ptr<T>> by T*
I have a set of shared pointers:
std::set<boost::shared_ptr<T>> set;
And a pointer:
T* p;
I would like to efficiently remove the element of set
equal to p
, but I can't do this w开发者_开发问答ith any of the members of set, or any of the standard algorithms, since T*
is a completely different type to boost::shared_ptr<T>
.
A few approaches I can think of are:
- somehow constructing a new shared_ptr from the pointer that won't take ownership of the pointed to memory (ideal solution, but I can't see how to do this)
- wrapping / re-implementing shared_ptr so that I can do the above
- just doing my own binary search over the set
Construct a shared_ptr<T>
from T
with a null_deleter
(see boost:::shared_ptr FAQ).
struct null_deleter {
void operator()(void const *) const { }
};
size_t remove_ptr_from_set(std::set<boost::shared_ptr<T>> &set, X* x)
{
shared_ptr<X> px(x, null_deleter());
return set.erase(px);
}
That way the types are compatible and you don't have to worry about your temporary shared_ptr deleting any object.
Or, as one of the comments say, if you can change T to inherit from enable_shared_from_this you could get a correct shared ptr from your object.
If the reason for using the set is that you need to efficiently find pointers of type T, then the obvious answer is not to make it a set of shared pointers! Instead, wrap the set in a class which manages the lifetimes of the pointers that the set contains.
You can use boost::ptr_set
if you want the set to have ownership of the objects, or boost::reference_wrapper
if you just want the set to store references to them. If you use shared_ptr
in one place in your code, you will have to use it in all places, or risk terrible crashes (dangling pointers, already deleted objects etc.). The exception is weak_ptr
, a pointer that points to an object held by a shared_ptr
but does not share ownership.
精彩评论