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_mapisn'tconst, so you're allowed to modify it. Moving from aunique_ptris 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:
// lockshould be replaced with a scoped lock guard.DoSomeExpensiveTaskon your localunique_ptrwithout first checking if it has a value or not.