Выбор ответа Senior Move-семантика спрашивают часто обновлено

move или forward в шаблоне

Вопрос

Обёртка template <class T> void log_and_store(T&& v) { store(std::move(v)); }. Что не так?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Для lvalue объект вызывающего переместится: нужно std::forward<T(v). Для forwarding-ссылки std::move безусловно делает rvalue, поэтому std::string name; logandstore(name); неожиданно опустошит name. std::forward<T вернёт lvalue для lvalue-аргумента и rvalue для rvalue. - Они различаются именно поведением…

Варианты ответа

  1. Ничего: std::move и std::forward взаимозаменяемы в этом месте
  2. Не скомпилируется для lvalue: std::move требует rvalue-аргумент
  3. Будет лишнее копирование для rvalue, их нужно передавать без std::move
  4. Для lvalue объект вызывающего переместится: нужно std::forward<T>(v)правильный ответ

Разбор

Для forwarding-ссылки std::move безусловно делает rvalue, поэтому std::string name; log_and_store(name); неожиданно опустошит name. std::forward<T> вернёт lvalue для lvalue-аргумента и rvalue для rvalue.

  • Они различаются именно поведением для lvalue.
  • Код компилируется, ошибка проявится в рантайме.
  • Для rvalue оба варианта перемещают, лишних копий нет.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.