#c #move-semantics #return-value-optimization
Вопрос:
У меня есть следующая реализация, которая возвращает последний элемент a std::list<T>
и удаляет его из списка:
std::list<T> list_;
T ReturnAndDeleteLast( )const
{
T last( list_.back() ); // copy it before delete it.
list_.pop_back();
return last;
}
Теперь вопрос в том, когда называть это так:
T tmp{};
for( .... )
{
// do we want to delete at this iteration?
//YES:
tmp = ReturnAndDeleteLast();
// do something with tmp..
}
Вопрос в том, будет ли a std::move
более эффективным в этом случае или я должен полагаться на RVO.
Комментарии:
1. Вы спрашиваете, следует ли вам использовать
return std::move(last);
? Если так, то нет. Все функциональные объекты локальной продолжительности автоматического хранения автоматически перемещаются, если их можно, а затем копируются, если их невозможно переместить.2. Вы могли бы сделать
T last( std::move(list_.back()) );
это для потенциальной выгоды. Конечно, загадка заключается в том, почему у вас естьconst
функция-член, изменяющая то, что выглядит как список участников.3.
return std::move(last);
предотвратите НРВО.return last;
может сделать NRVO, а в худшем случае переместиться (так как список подвижен).4. @Рассказчик-АнсландерМоника Я думал об этом. Но я не уверен, что происходит с объектом
list_.back()
. Он удален? Означает ли это, что мне, например, это не нужноlist_.pop_back()
?5. Нет, семантика перемещения работает не так. У вас есть измененный объект, оставленный там в некотором разрушаемом/назначаемом состоянии. Вы хлопаете, чтобы устранить это. Но любые ресурсы, которыми он, возможно, располагал внутри страны, уже переведены на местный
last
уровень . Думайте о поверхностном копировании, а не о глубоком копировании, как у вас сейчас.