Is it safe to move unique_ptr from a container and erase it?

821 Views Asked by At

I am wondering the following pattern is safe to use and recommendable? First, I'd like to move a unique_ptr found from a container to another temporary unique_ptr and then erase it from the container. Then, call an actual method using the moved pointer.

This is to avoid locking the entire container while calling some expensive method.

Please see the following example:

std::unordered_map<string, std::unique_ptr<Sample>> samples;

std::unique_ptr<Sample> ptr_to_remove;

// Lock (reader lock) samples here.
auto it = samples.find(name);
if (it != samples.end()) {
   ptr_to_remove = std::move(it->second);
   samples.erase(it);
}
// Unlock samples here.

if (ptr_to_remove) {
    ptr_to_remove->DoSomeExpensiveTask();
}
1

There are 1 best solutions below

1
On BEST ANSWER

Yes, it's safe.

The value type of unordered_map isn't const, so you're allowed to modify it. Moving from a unique_ptr is safe. Erasing the item from the map will invoke the destructor on the unique_ptr, which will destroy the now-empty unique_ptr, which is also safe.

The only potentially unsafe parts of your code example are:

  • The comments about // lock should be replaced with a scoped lock guard.
  • I realize this is probably just for exposition, but you're invoking DoSomeExpensiveTask on your local unique_ptr without first checking if it has a value or not.