Ответ вслух Senior Move-семантика обновлено

Perfect forwarding

Вопрос

Что такое perfect forwarding? Объясните forwarding-ссылки, схлопывание ссылок и std::forward на примере фабрики.

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

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

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

Коротко

Perfect forwarding решает задачу обёртки: принять аргументы любого вида и передать их дальше ровно такими же, lvalue как lvalue, rvalue как rvalue, сохранив const. Для этого параметр объявляют T&&, где T выводится, это forwarding-ссылка.

Что должно прозвучать в ответе

  • Задача: передать аргументы дальше, сохранив категорию и константность

  • Forwarding-ссылка `T&&` с выводимым T

  • Вывод T как U& для lvalue и схлопывание ссылок

  • `std::forward<T>` условно приводит к rvalue

  • Примеры: make_unique, emplace_back, std::invoke-обёртки

  • Ловушки: перегрузка с forwarding-ссылкой перехватывает слишком много, forward дважды

Что могут спросить следом

  • Почему нельзя дважды вызвать std::forward на одном аргументе?
  • Почему конструктор с forwarding-ссылкой опасен рядом с копирующим конструктором?

Разбор

Perfect forwarding решает задачу обёртки: принять аргументы любого вида и передать их дальше ровно такими же, lvalue как lvalue, rvalue как rvalue, сохранив const. Для этого параметр объявляют T&&, где T выводится, это forwarding-ссылка. Если передали lvalue типа U, T выводится как U&, и U& && по правилу схлопывания даёт U&. Если rvalue, T = U и параметр U&&. Внутри функции параметр всё равно lvalue, потому что у него есть имя, и std::forward<T>(x) возвращает его в исходной категории: при T = U& это lvalue, при T = U это static_cast<U&&>. Так устроены std::make_unique<T>(std::forward<Args>(args)...) и emplace_back. Ловушки: после std::forward rvalue-аргумент может быть уже перемещён, поэтому дважды его форвардить нельзя; шаблонный конструктор с forwarding-ссылкой выигрывает перегрузку у копирующего конструктора для неконстантного lvalue, его ограничивают концептами или enable_if.

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

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