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();
}
Yes, it's safe.
The value type of
unordered_map
isn'tconst
, so you're allowed to modify it. Moving from aunique_ptr
is safe. Erasing the item from the map will invoke the destructor on theunique_ptr
, which will destroy the now-emptyunique_ptr
, which is also safe.The only potentially unsafe parts of your code example are:
// lock
should be replaced with a scoped lock guard.DoSomeExpensiveTask
on your localunique_ptr
without first checking if it has a value or not.