I have a class that stores weak_ptrs in a container and later does something if the weak_ptr is not expired:
class Example
{
public:
void fill(std::shared_ptr<int> thing)
{
member.push_back(thing);
}
void dosomething() const
{
for (const auto& i : member)
if (!i.expired())
;// do something. the weak_ptr will not be locked
}
private:
std::vector<std::weak_ptr<int>> member;
};
If Example
is an object that lives forever and fill
is used regularily, the vector allocates memory for elements continously, but they are never removed after they expired.
Is there any automatic C++ way to get rid of the expired weak_ptrs in the container or is there a better way to store a variable number of them?
My naive way would be to iterate over the container each time fill
is called and remove all the expired weak_ptrs. In scenarios where Example
has many elements in the container and fill is frequently called this seems to be very inefficient.
Does the
shared_ptr<int>
have to be ashared_ptr<int>
?How about a
shared_ptr<IntWrapper>
?I would rather use a custom deleter for the shared_ptr. But this implies here to change the interface of the Example class. The advantage using custom deleter is that there is no need to check for expired objects in the collection. The collection is directly maintained by the custom deleter.
Quick implementation :
Since you clarified that you are actually using a
std::map
and not astd::vector
, it might be easiest to remove the expired elements on-the-fly indoSomething()
. Switch back from a range-based for loop to a normal iterator based design: