2016-12-19 6 views
0

Мне интересно, что следующий шаблон безопасен в использовании и рекомендуется? Во-первых, я хотел бы переместить unique_ptr, найденный из контейнера, в другой временный unique_ptr, а затем удалить его из контейнера. Затем вызовите фактический метод с помощью перемещенного указателя.Безопасно ли переместить unique_ptr из контейнера и удалить его?

Это необходимо, чтобы избежать блокировки всего контейнера при вызове дорогостоящего метода.

Пожалуйста, смотрите следующий пример:

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(); 
} 
+0

Что произошло, когда вы попробовали? –

+1

it-> second - это объект 'Sample', а не' unique_ptr'. Вы имели в виду 'std :: unordered_map > samples;'? (Для компиляции кода). –

+0

A.S.H, да. это правильно :) Обновился вопрос – MaxHeap

ответ

2

Да, это безопасно.

Тип значения unordered_map не является const, поэтому вам разрешено его модифицировать. Перемещение с unique_ptr безопасно. Стирание элемента с карты вызовет деструктор на unique_ptr, который уничтожит теперь пустой unique_ptr, что также безопасно.

Единственные потенциально опасные части вашего примера кода являются:

  • Комментарии о // lock должны быть заменены контекстными блокировки охраны.
  • Я понимаю, что это, вероятно, только для экспозиции, но вы вызываете DoSomeExpensiveTask на свой местный unique_ptr без предварительной проверки, имеет ли оно значение или нет.
+0

О, я вижу. Благодарю. Обновлен вопрос (добавление проверки кода, если указатель имеет значение) – MaxHeap