Подтвердить что ты не робот

С++ 11 перемещается при возврате блокировки

В книге "С++ Concurrency в действии", читающей следующий метод

std::unique_lock<std::mutex> wait_for_data()
{
    std::unique_lock<std::mutex> head_lock(head_mutex);
    data_cond.wait(head_lock,[&]{return head.get()!=get_tail();});
    return std::move(head_lock);
 }

Я не могу понять, почему head_lock является std:: move-ed при возврате. Мое понятие и ощущение кишки использования перемещения и RVO соответствуют мнению, разделяемому в С++ 11 rvalues ​​и перемещению семантики (return statement)

Но я, как правило, доверяю автору знать лучше. Может ли кто-нибудь уточнить, когда std:: переместить возвращаемое значение лучше, и есть ли что-то конкретное о замках? Спасибо.

4b9b3361

Ответ 1

Это нормально с или без std::move. Имя локальной переменной * рассматривается как rvalue в операторе return, в результате чего в обоих случаях вызывается конструктор перемещения. Авторы предположительно использовали std::move по стилистическим соображениям, чтобы было ясно, что блокировка перемещается. Это мешает NRVO, но стоимость перемещения unique_lock здесь, вероятно, минимальна по сравнению со стоимостью блокировки и ожидания.

В словах @Deduplicator это "пессимизация, чтобы подчеркнуть фактическую семантику".

Вы можете проверить это самостоятельно - unique_lock не может быть скопирован, поэтому return head_lock; не будет скомпилирован, если бы это была копия.


* Это правило С++ 14. Правило С++ 11 ограничено случаями, когда разрешение на копирование разрешено или разрешено, за исключением того факта, что переменная является параметром функции. Эта разница несущественна в этом вопросе, так как head_lock, очевидно, подходит для копирования.Суб >